Add and document g_mount_is_shadowed plus calls to set/unset a mount as
authorAlexander Larsson <alexl@redhat.com>
Mon, 1 Dec 2008 13:46:11 +0000 (13:46 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Mon, 1 Dec 2008 13:46:11 +0000 (13:46 +0000)
2008-12-01  Alexander Larsson  <alexl@redhat.com>

        * gio.symbols:
        * gmount.[ch]:
        * gunionvolumemonitor.c:
        * gvolume.c:
Add and document g_mount_is_shadowed plus calls
to set/unset a mount as shadowed

svn path=/trunk/; revision=7716

docs/reference/ChangeLog
docs/reference/gio/gio-sections.txt
gio/ChangeLog
gio/gio.symbols
gio/gmount.c
gio/gmount.h
gio/gunionvolumemonitor.c
gio/gvolume.c

index 9c47c026927d0994017424637c8db27ec50c5f73..041d586258e0a2a7f7a96a679fc09b839435e86b 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-01  Alexander Larsson  <alexl@redhat.com>
+
+        Reviewed by NOBODY (OOPS!).
+
+        * gio/gio-sections.txt:
+
 2008-11-30  Matthias Clasen  <mclasen@redhat.com>
 
        * glib/running.sgml: Mention all and help special options in
index c54272cf999a17e0c5ed59978c1416c3a39b7b03..0e5dd4262c0920efec21fa05c28531001d8f4d3b 100644 (file)
@@ -863,6 +863,9 @@ g_mount_eject_finish
 g_mount_guess_content_type
 g_mount_guess_content_type_finish
 g_mount_guess_content_type_sync
+g_mount_is_shadowed
+g_mount_shadow
+g_mount_unshadow
 <SUBSECTION Standard>
 G_IS_MOUNT
 G_MOUNT
index c1f38b84f1029560397a295bf90f4a4847c14a66..d4de9470d479298c780438be65f253bd872ccc07 100644 (file)
@@ -1,3 +1,12 @@
+2008-12-01  Alexander Larsson  <alexl@redhat.com>
+
+        * gio.symbols:
+        * gmount.[ch]:
+        * gunionvolumemonitor.c:
+        * gvolume.c:
+       Add and document g_mount_is_shadowed plus calls
+       to set/unset a mount as shadowed
+       
 2008-11-28  Matthias Clasen  <mclasen@redhat.com>
 
        * gio/tests/g-icon.c: Comment out two failing tests
index 3be198820fb417c733bcd59291206583a3fb8857..625666681e13682391902b12b7d3f05e4517cadd 100644 (file)
@@ -727,6 +727,9 @@ g_mount_remount_finish
 g_mount_guess_content_type
 g_mount_guess_content_type_finish
 g_mount_guess_content_type_sync
+g_mount_is_shadowed
+g_mount_shadow
+g_mount_unshadow
 #endif
 #endif
 
index 3c8ae6182981a5607d2ab9761c87fb9ff80dd1f9..dbdbeaf498f1e87ae0cb1db2c4468444994a22ec 100644 (file)
@@ -695,5 +695,139 @@ g_mount_guess_content_type_sync (GMount              *mount,
   return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
 }
 
+G_LOCK_DEFINE_STATIC (priv_lock);
+
+/* only access this structure when holding priv_lock */
+typedef struct
+{
+  gint shadow_ref_count;
+} GMountPrivate;
+
+static void
+free_private (GMountPrivate *private)
+{
+  G_LOCK (priv_lock);
+  g_free (private);
+  G_UNLOCK (priv_lock);
+}
+
+/* may only be called when holding priv_lock */
+static GMountPrivate *
+get_private (GMount *mount)
+{
+  GMountPrivate *private;
+
+  private = g_object_get_data (G_OBJECT (mount), "g-mount-private");
+  if (G_LIKELY (private != NULL))
+    goto out;
+
+  private = g_new0 (GMountPrivate, 1);
+  g_object_set_data_full (G_OBJECT (mount),
+                          "g-mount-private",
+                          private,
+                          (GDestroyNotify) free_private);
+
+ out:
+  return private;
+}
+
+/**
+ * g_mount_is_shadowed:
+ * @mount: A #GMount.
+ *
+ * Determines if @mount is shadowed. Applications or libraries should
+ * avoid displaying @mount in the user interface if it is shadowed.
+ *
+ * A mount is said to be shadowed if there exists one or more user
+ * visible objects (currently #GMount objects) with a root that is
+ * inside the root of @mount.
+ *
+ * One application of shadow mounts is when exposing a single file
+ * system that is used to address several logical volumes. In this
+ * situation, a #GVolumeMonitor implementation would create two
+ * #GVolume objects (for example, one for the camera functionality of
+ * the device and one for a SD card reader on the device) with
+ * activation URIs <literal>gphoto2://[usb:001,002]/store1/</literal>
+ * and <literal>gphoto2://[usb:001,002]/store2/</literal>. When the
+ * underlying mount (with root
+ * <literal>gphoto2://[usb:001,002]/</literal>) is mounted, said
+ * #GVolumeMonitor implementation would create two #GMount objects
+ * (each with their root matching the corresponding volume activation
+ * root) that would shadow the original mount.
+ *
+ * The proxy monitor in GVfs 2.26 and later, automatically creates and
+ * manage shadow mounts (and shadows the underlying mount) if the
+ * activation root on a #GVolume is set.
+ *
+ * Returns: %TRUE if @mount is shadowed.
+ *
+ * Since: 2.20
+ **/
+gboolean
+g_mount_is_shadowed (GMount *mount)
+{
+  GMountPrivate *priv;
+  gboolean ret;
+
+  g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
+
+  G_LOCK (priv_lock);
+  priv = get_private (mount);
+  ret = (priv->shadow_ref_count > 0);
+  G_UNLOCK (priv_lock);
+
+  return ret;
+}
+
+/**
+ * g_mount_shadow:
+ * @mount: A #GMount.
+ *
+ * Increments the shadow count on @mount. Usually used by
+ * #GVolumeMonitor implementations when creating a shadow mount for
+ * @mount, see g_mount_is_shadowed() for more information. The caller
+ * will need to emit the #GMount::changed signal on @mount manually.
+ *
+ * Since: 2.20
+ **/
+void
+g_mount_shadow (GMount *mount)
+{
+  GMountPrivate *priv;
+
+  g_return_if_fail (G_IS_MOUNT (mount));
+
+  G_LOCK (priv_lock);
+  priv = get_private (mount);
+  priv->shadow_ref_count += 1;
+  G_UNLOCK (priv_lock);
+}
+
+/**
+ * g_mount_unshadow:
+ * @mount: A #GMount.
+ *
+ * Decrements the shadow count on @mount. Usually used by
+ * #GVolumeMonitor implementations when destroying a shadow mount for
+ * @mount, see g_mount_is_shadowed() for more information. The caller
+ * will need to emit the #GMount::changed signal on @mount manually.
+ *
+ * Since: 2.20
+ **/
+void
+g_mount_unshadow (GMount *mount)
+{
+  GMountPrivate *priv;
+
+  g_return_if_fail (G_IS_MOUNT (mount));
+
+  G_LOCK (priv_lock);
+  priv = get_private (mount);
+  priv->shadow_ref_count -= 1;
+  if (priv->shadow_ref_count < 0)
+    g_warning ("Shadow ref count on GMount is negative");
+  G_UNLOCK (priv_lock);
+}
+
 #define __G_MOUNT_C__
 #include "gioaliasdef.c"
index 66304bf7be7729622e600e07575570c5cff25742..027960d5a8aa6db0e5feac8cfbb2314babbfd617 100644 (file)
@@ -61,8 +61,8 @@ typedef struct _GMountIface    GMountIface;
  * @guess_content_type: Starts guessing the type of the content of a #GMount.
  *     See g_mount_guess_content_type() for more information on content
  *     type guessing. This operation was added in 2.18.
- * @guess_content_type_finish: Finishes a contenet type guessing operation.
- * @guess_content_type_sync: Synchronous variant of @guess_content_type.
+ * @guess_content_type_finish: Finishes a contenet type guessing operation. Added in 2.18.
+ * @guess_content_type_sync: Synchronous variant of @guess_content_type. Added in 2.18
  *
  * Interface for implementing operations for mounts.
  **/
@@ -180,6 +180,10 @@ gchar    ** g_mount_guess_content_type_sync   (GMount              *mount,
                                                GCancellable        *cancellable,
                                                GError             **error);
 
+gboolean    g_mount_is_shadowed               (GMount              *mount);
+void        g_mount_shadow                    (GMount              *mount);
+void        g_mount_unshadow                  (GMount              *mount);
+
 G_END_DECLS
 
 #endif /* __G_MOUNT_H__ */
index f12ecd905e96f5b68968f6205fbdf6ab38b4c6e9..1b5bafd6f343170dfe00b999eab6bceccb1d6de5 100644 (file)
@@ -638,7 +638,8 @@ _g_mount_get_for_mount_path (const char *mount_path,
  * Deprecated: 2.20: Instead of using this function, #GVolumeMonitor
  * implementations should instead create shadow mounts with the URI of
  * the mount they intend to adopt. See the proxy volume monitor in
- * gvfs for an example of this.
+ * gvfs for an example of this. Also see g_mount_is_shadowed(),
+ * g_mount_shadow() and g_mount_unshadow() functions.
  */
 GVolume *
 g_volume_monitor_adopt_orphan_mount (GMount *mount)
index 7607b429036f2f5142fdf8b02dc4fe1901242f43..ef550d8228c378f6b475105c6c198888630c7f2b 100644 (file)
@@ -566,37 +566,9 @@ g_volume_enumerate_identifiers (GVolume *volume)
  *
  * will always be %TRUE.
  *
- * There is a number of possible uses of this function.
- *
- * First, implementations of #GVolumeMonitor can use this method to
- * determine if a #GMount should be adopted in the implementation of
- * g_volume_monitor_adopt_orphan_mount() by testing if the result of
- * this function equals (or has as prefix) the root of the given
- * #GMount. In particular this is useful in the in-process proxy part
- * of an out-of-process volume monitor implementation.
- *
- * Second, applications such as a file manager can use this to
- * navigate to the correct root in response to the user navigating to
- * a server. Now suppose there is a volume monitor for networked
- * servers that creates #GVolume objects corresponding to the
- * "favorite servers" (e.g. set up by the user via some "Connect to
- * Server" dialog). Suppose also that one of the favorite servers is
- * named "public_html @ fd.o" and the URI is
- * <literal>sftp://people.freedesktop.org/home/david/public_html</literal>.
- *
- * Now, due to the way GIO works, when the corresponding #GVolume is
- * mounted then a #GMount (typically adopted by the volume monitor)
- * will appear with the mount root (e.g. the result of
- * g_mount_get_root())
- * <literal>sftp://people.freedesktop.org</literal>. However, this
- * function (g_volume_get_activation_root()) can return a #GFile for
- * the URI
- * <literal>sftp://people.freedesktop.org/home/david/public_html</literal>.
- *
- * All this means that a file manager can use the latter URI for
- * navigating when the user clicks an icon representing the #GVolume
- * (e.g. clicking an icon with the name "public_html @ fd.o" or
- * similar).
+ * Activation roots are typically used in #GVolumeMonitor
+ * implementations to find the underlying mount to shadow, see
+ * g_mount_is_shadowed() for more details.
  *
  * Returns: the activation root of @volume or %NULL. Use
  * g_object_unref() to free.