cleanup
[platform/upstream/glib.git] / gio / gunionvolumemonitor.c
index b3815d8..4c3049b 100644 (file)
@@ -1,3 +1,5 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
 /* GIO - GLib Input, Output and Streaming Library
  * 
  * Copyright (C) 2006-2007 Red Hat, Inc.
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Larsson <alexl@redhat.com>
  *         David Zeuthen <davidz@redhat.com>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <string.h>
 
@@ -36,7 +36,6 @@
 
 #include "glibintl.h"
 
-#include "gioalias.h"
 
 struct _GUnionVolumeMonitor {
   GVolumeMonitor parent;
@@ -51,8 +50,8 @@ static void g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_mo
 #define g_union_volume_monitor_get_type _g_union_volume_monitor_get_type
 G_DEFINE_TYPE (GUnionVolumeMonitor, g_union_volume_monitor, G_TYPE_VOLUME_MONITOR);
 
+static GRecMutex the_volume_monitor_mutex;
 
-G_LOCK_DEFINE_STATIC(the_volume_monitor);
 static GUnionVolumeMonitor *the_volume_monitor = NULL;
 
 static void
@@ -63,31 +62,38 @@ g_union_volume_monitor_finalize (GObject *object)
 
   monitor = G_UNION_VOLUME_MONITOR (object);
 
-  while (monitor->monitors != NULL) {
-    child_monitor = monitor->monitors->data;
-    g_union_volume_monitor_remove_monitor (monitor, 
-                                           child_monitor);
-    g_object_unref (child_monitor);
-  }
+  while (monitor->monitors != NULL)
+    {
+      child_monitor = monitor->monitors->data;
+      g_union_volume_monitor_remove_monitor (monitor, 
+                                             child_monitor);
+      g_object_unref (child_monitor);
+    }
 
-  
-  if (G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->finalize)
-    (*G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->finalize) (object);
+  G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->finalize (object);
 }
 
 static void
 g_union_volume_monitor_dispose (GObject *object)
 {
   GUnionVolumeMonitor *monitor;
-  
+  GVolumeMonitor *child_monitor;
+  GList *l;
+
   monitor = G_UNION_VOLUME_MONITOR (object);
 
-  G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
   the_volume_monitor = NULL;
-  G_UNLOCK (the_volume_monitor);
+
+  for (l = monitor->monitors; l != NULL; l = l->next)
+    {
+      child_monitor = l->data;
+      g_object_run_dispose (G_OBJECT (child_monitor));
+    }
   
-  if (G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->dispose)
-    (*G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->dispose) (object);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
+
+  G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->dispose (object);
 }
 
 static GList *
@@ -102,7 +108,7 @@ get_mounts (GVolumeMonitor *volume_monitor)
 
   res = NULL;
   
-  G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
 
   for (l = monitor->monitors; l != NULL; l = l->next)
     {
@@ -111,7 +117,7 @@ get_mounts (GVolumeMonitor *volume_monitor)
       res = g_list_concat (res, g_volume_monitor_get_mounts (child_monitor));
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return res;
 }
@@ -128,7 +134,7 @@ get_volumes (GVolumeMonitor *volume_monitor)
 
   res = NULL;
   
-  G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
 
   for (l = monitor->monitors; l != NULL; l = l->next)
     {
@@ -137,7 +143,7 @@ get_volumes (GVolumeMonitor *volume_monitor)
       res = g_list_concat (res, g_volume_monitor_get_volumes (child_monitor));
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return res;
 }
@@ -154,7 +160,7 @@ get_connected_drives (GVolumeMonitor *volume_monitor)
 
   res = NULL;
   
-  G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
 
   for (l = monitor->monitors; l != NULL; l = l->next)
     {
@@ -163,7 +169,7 @@ get_connected_drives (GVolumeMonitor *volume_monitor)
       res = g_list_concat (res, g_volume_monitor_get_connected_drives (child_monitor));
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return res;
 }
@@ -180,7 +186,7 @@ get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
 
   volume = NULL;
   
-  G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
 
   for (l = monitor->monitors; l != NULL; l = l->next)
     {
@@ -192,7 +198,7 @@ get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
 
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return volume;
 }
@@ -209,7 +215,7 @@ get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
 
   mount = NULL;
   
-  G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
 
   for (l = monitor->monitors; l != NULL; l = l->next)
     {
@@ -221,7 +227,7 @@ get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
 
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return mount;
 }
@@ -248,7 +254,7 @@ child_volume_added (GVolumeMonitor      *child_monitor,
                     GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "volume_added",
+                        "volume-added",
                         child_volume);
 }
 
@@ -258,7 +264,7 @@ child_volume_removed (GVolumeMonitor      *child_monitor,
                       GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "volume_removed",
+                        "volume-removed",
                         child_volume);
 }
 
@@ -268,7 +274,7 @@ child_volume_changed (GVolumeMonitor      *child_monitor,
                       GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "volume_changed",
+                        "volume-changed",
                         child_volume);
 }
 
@@ -278,7 +284,7 @@ child_mount_added (GVolumeMonitor      *child_monitor,
                    GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                         "mount_added",
+                         "mount-added",
                          child_mount);
 }
 
@@ -288,7 +294,7 @@ child_mount_removed (GVolumeMonitor      *child_monitor,
                      GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "mount_removed",
+                        "mount-removed",
                         child_mount);
 }
 
@@ -298,7 +304,7 @@ child_mount_pre_unmount (GVolumeMonitor       *child_monitor,
                           GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "mount_pre_unmount",
+                        "mount-pre-unmount",
                         child_mount);
 }
 
@@ -309,7 +315,7 @@ child_mount_changed (GVolumeMonitor       *child_monitor,
                       GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "mount_changed",
+                        "mount-changed",
                         child_mount);
 }
 
@@ -319,7 +325,7 @@ child_drive_connected (GVolumeMonitor      *child_monitor,
                        GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "drive_connected",
+                        "drive-connected",
                         child_drive);
 }
 
@@ -329,7 +335,7 @@ child_drive_disconnected (GVolumeMonitor      *child_monitor,
                           GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                        "drive_disconnected",
+                        "drive-disconnected",
                         child_drive);
 }
 
@@ -339,7 +345,27 @@ child_drive_changed (GVolumeMonitor      *child_monitor,
                      GUnionVolumeMonitor *union_monitor)
 {
   g_signal_emit_by_name (union_monitor,
-                         "drive_changed",
+                         "drive-changed",
+                         child_drive);
+}
+
+static void
+child_drive_eject_button (GVolumeMonitor      *child_monitor,
+                          GDrive             *child_drive,
+                          GUnionVolumeMonitor *union_monitor)
+{
+  g_signal_emit_by_name (union_monitor,
+                         "drive-eject-button",
+                         child_drive);
+}
+
+static void
+child_drive_stop_button (GVolumeMonitor      *child_monitor,
+                         GDrive             *child_drive,
+                         GUnionVolumeMonitor *union_monitor)
+{
+  g_signal_emit_by_name (union_monitor,
+                         "drive-stop-button",
                          child_drive);
 }
 
@@ -354,16 +380,18 @@ g_union_volume_monitor_add_monitor (GUnionVolumeMonitor *union_monitor,
     g_list_prepend (union_monitor->monitors,
                    g_object_ref (volume_monitor));
 
-  g_signal_connect (volume_monitor, "volume_added", (GCallback)child_volume_added, union_monitor);
-  g_signal_connect (volume_monitor, "volume_removed", (GCallback)child_volume_removed, union_monitor);
-  g_signal_connect (volume_monitor, "volume_changed", (GCallback)child_volume_changed, union_monitor);
-  g_signal_connect (volume_monitor, "mount_added", (GCallback)child_mount_added, union_monitor);
-  g_signal_connect (volume_monitor, "mount_removed", (GCallback)child_mount_removed, union_monitor);
-  g_signal_connect (volume_monitor, "mount_pre_unmount", (GCallback)child_mount_pre_unmount, union_monitor);
-  g_signal_connect (volume_monitor, "mount_changed", (GCallback)child_mount_changed, union_monitor);
-  g_signal_connect (volume_monitor, "drive_connected", (GCallback)child_drive_connected, union_monitor);
-  g_signal_connect (volume_monitor, "drive_disconnected", (GCallback)child_drive_disconnected, union_monitor);
-  g_signal_connect (volume_monitor, "drive_changed", (GCallback)child_drive_changed, union_monitor);
+  g_signal_connect (volume_monitor, "volume-added", (GCallback)child_volume_added, union_monitor);
+  g_signal_connect (volume_monitor, "volume-removed", (GCallback)child_volume_removed, union_monitor);
+  g_signal_connect (volume_monitor, "volume-changed", (GCallback)child_volume_changed, union_monitor);
+  g_signal_connect (volume_monitor, "mount-added", (GCallback)child_mount_added, union_monitor);
+  g_signal_connect (volume_monitor, "mount-removed", (GCallback)child_mount_removed, union_monitor);
+  g_signal_connect (volume_monitor, "mount-pre-unmount", (GCallback)child_mount_pre_unmount, union_monitor);
+  g_signal_connect (volume_monitor, "mount-changed", (GCallback)child_mount_changed, union_monitor);
+  g_signal_connect (volume_monitor, "drive-connected", (GCallback)child_drive_connected, union_monitor);
+  g_signal_connect (volume_monitor, "drive-disconnected", (GCallback)child_drive_disconnected, union_monitor);
+  g_signal_connect (volume_monitor, "drive-changed", (GCallback)child_drive_changed, union_monitor);
+  g_signal_connect (volume_monitor, "drive-eject-button", (GCallback)child_drive_eject_button, union_monitor);
+  g_signal_connect (volume_monitor, "drive-stop-button", (GCallback)child_drive_stop_button, union_monitor);
 }
 
 static void
@@ -388,136 +416,126 @@ g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor,
   g_signal_handlers_disconnect_by_func (child_monitor, child_drive_connected, union_monitor);
   g_signal_handlers_disconnect_by_func (child_monitor, child_drive_disconnected, union_monitor);
   g_signal_handlers_disconnect_by_func (child_monitor, child_drive_changed, union_monitor);
+  g_signal_handlers_disconnect_by_func (child_monitor, child_drive_eject_button, union_monitor);
+  g_signal_handlers_disconnect_by_func (child_monitor, child_drive_stop_button, union_monitor);
 }
 
-/* Note: This compares in reverse order.
-   Higher prio -> sort first
- */
-static gint
-compare_monitor_type (gconstpointer  a,
-                     gconstpointer  b,
-                     gpointer       user_data)
-{
-  GNativeVolumeMonitorClass *class_a, *class_b;
-  gint res;
-  const char *use_this_monitor;
-
-  /* We ref:ed all the classes, so the peek is safe */
-  class_a = g_type_class_peek (*(GType *)a);
-  class_b = g_type_class_peek (*(GType *)b);
-  use_this_monitor = user_data;
-
-  if (class_a == class_b)
-    res = 0;
-  else if (use_this_monitor != NULL &&
-          strcmp (class_a->name, use_this_monitor) == 0)
-    res = -1;
-  else if (use_this_monitor != NULL &&
-          strcmp (class_b->name, use_this_monitor) == 0)
-    res = 1;
-  else 
-    res = class_b->priority - class_a->priority;
-  
-  return res;
-}
-
-static GTypeClass *
+static GType
 get_default_native_class (gpointer data)
 {
-  GNativeVolumeMonitorClass *klass;
-  GType *monitors;
-  guint n_monitors;
-  GTypeClass *native_class;
+  GNativeVolumeMonitorClass *klass, *native_class, **native_class_out;
   const char *use_this;
-  int i;
+  GIOExtensionPoint *ep;
+  GIOExtension *extension;
+  GList *l;
 
+  native_class_out = data;
+  
   use_this = g_getenv ("GIO_USE_VOLUME_MONITOR");
   
-#ifdef G_OS_UNIX
-  /* Ensure GUnixVolumeMonitor type is available */
-  {
-    volatile GType unix_type;
-    /* volatile is required to avoid any G_GNUC_CONST optimizations */
-    unix_type = _g_unix_volume_monitor_get_type ();
-  }
-#endif
-      
   /* Ensure vfs in modules loaded */
   _g_io_modules_ensure_loaded ();
 
-  monitors = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_monitors);
-
-  /* Ref all classes once so we don't load/unload them a lot */
-  for (i = 0; i < n_monitors; i++)
-    g_type_class_ref (monitors[i]);
-  
-  g_qsort_with_data (monitors, n_monitors, sizeof (GType),
-                    compare_monitor_type, (gpointer)use_this);
+  ep = g_io_extension_point_lookup (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
 
   native_class = NULL;
-  for (i = 0; i < n_monitors; i++)
+  if (use_this)
     {
-      klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (monitors[i]));
-
-      if (klass->is_supported ())
+      extension = g_io_extension_point_get_extension_by_name (ep, use_this);
+      if (extension)
        {
-         native_class = (GTypeClass *)klass;
-         break;
+         klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
+         if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
+           native_class = klass;
+         else
+           g_type_class_unref (klass);
        }
-      g_type_class_unref (klass);
     }
 
-  for (i = 0; i < n_monitors; i++)
-    g_type_class_unref (g_type_class_peek (monitors[i]));
-
-  g_free (monitors);
-
-  return native_class;
+  if (native_class == NULL)
+    {
+      for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
+       {
+         extension = l->data;
+         klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
+         if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
+           {
+             native_class = klass;
+             break;
+           }
+         else
+           g_type_class_unref (klass);
+       }
+    }
+  if (native_class)
+    {
+      *native_class_out = native_class;
+      return G_TYPE_FROM_CLASS (native_class);
+    }
+  else
+    return G_TYPE_INVALID;
 }
 
-
-static GType
-get_native_type ()
+/* We return the class, with a ref taken.
+ * This way we avoid unloading the class/module
+ * between selecting the type and creating the
+ * instance on the first call.
+ */
+static GNativeVolumeMonitorClass *
+get_native_class (void)
 {
-  static GOnce _once_init = G_ONCE_INIT;
+  static GOnce once_init = G_ONCE_INIT;
+  GTypeClass *type_class;
 
-  g_once (&_once_init, (GThreadFunc)get_default_native_class, NULL);
+  type_class = NULL;
+  g_once (&once_init, (GThreadFunc)get_default_native_class, &type_class);
 
-  return G_TYPE_FROM_CLASS (_once_init.retval);
+  if (type_class == NULL && once_init.retval != GUINT_TO_POINTER(G_TYPE_INVALID))
+    type_class = g_type_class_ref ((GType)once_init.retval);
+  
+  return (GNativeVolumeMonitorClass *)type_class;
 }
 
 static void
 g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor)
 {
+}
+
+static void
+populate_union_monitor (GUnionVolumeMonitor *union_monitor)
+{
   GVolumeMonitor *monitor;
-  GType *monitors;
-  guint n_monitors;
-  GType native_type;
-  int i;
+  GNativeVolumeMonitorClass *native_class;
+  GVolumeMonitorClass *klass;
+  GIOExtensionPoint *ep;
+  GIOExtension *extension;
+  GList *l;
 
-  native_type = get_native_type ();
+  native_class = get_native_class ();
 
-  if (native_type != G_TYPE_INVALID)
+  if (native_class != NULL)
     {
-      monitor = g_object_new (native_type, NULL);
+      monitor = g_object_new (G_TYPE_FROM_CLASS (native_class), NULL);
       g_union_volume_monitor_add_monitor (union_monitor, monitor);
       g_object_unref (monitor);
+      g_type_class_unref (native_class);
     }
-  
-  monitors = g_type_children (G_TYPE_VOLUME_MONITOR, &n_monitors);
-  
-  for (i = 0; i < n_monitors; i++)
+
+  ep = g_io_extension_point_lookup (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
+  for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
     {
-      if (monitors[i] == G_TYPE_UNION_VOLUME_MONITOR ||
-         g_type_is_a (monitors[i], G_TYPE_NATIVE_VOLUME_MONITOR))
-       continue;
+      extension = l->data;
       
-      monitor = g_object_new (monitors[i], NULL);
-      g_union_volume_monitor_add_monitor (union_monitor, monitor);
-      g_object_unref (monitor);
+      klass = G_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
+      if (klass->is_supported == NULL || klass->is_supported())
+       {
+         monitor = g_object_new (g_io_extension_get_type (extension), NULL);
+         g_union_volume_monitor_add_monitor (union_monitor, monitor);
+         g_object_unref (monitor);
+       }
+      g_type_class_unref (klass);
     }
-      
-  g_free (monitors);
 }
 
 static GUnionVolumeMonitor *
@@ -535,7 +553,7 @@ g_union_volume_monitor_new (void)
  * 
  * Gets the volume monitor used by gio.
  *
- * Returns: a reference to the #GVolumeMonitor used by gio. Call
+ * Returns: (transfer full): a reference to the #GVolumeMonitor used by gio. Call
  *    g_object_unref() when done with it.
  **/
 GVolumeMonitor *
@@ -543,49 +561,40 @@ g_volume_monitor_get (void)
 {
   GVolumeMonitor *vm;
   
-  G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
 
   if (the_volume_monitor)
     vm = G_VOLUME_MONITOR (g_object_ref (the_volume_monitor));
   else
     {
       the_volume_monitor = g_union_volume_monitor_new ();
+      populate_union_monitor (the_volume_monitor);
       vm = G_VOLUME_MONITOR (the_volume_monitor);
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return vm;
 }
 
-/**
- * _g_mount_get_for_mount_path:
- * @mountpoint: a string.
- * @cancellable: a #GCancellable, or %NULL
- * 
- * Returns: a #GMount for given @mount_path or %NULL.  
- **/
 GMount *
-_g_mount_get_for_mount_path (const char *mount_path,
+_g_mount_get_for_mount_path (const gchar  *mount_path,
                             GCancellable *cancellable)
 {
-  GType native_type;
   GNativeVolumeMonitorClass *klass;
   GMount *mount;
   
-  native_type = get_native_type ();
-
-  if (native_type == G_TYPE_INVALID)
+  klass = get_native_class ();
+  if (klass == NULL)
     return NULL;
 
   mount = NULL;
 
-  klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (native_type));
   if (klass->get_mount_for_mount_path)
     {
-      G_LOCK (the_volume_monitor);
+      g_rec_mutex_lock (&the_volume_monitor_mutex);
       mount = klass->get_mount_for_mount_path (mount_path, cancellable);
-      G_UNLOCK (the_volume_monitor);
+      g_rec_mutex_unlock (&the_volume_monitor_mutex);
     }
 
   /* TODO: How do we know this succeeded? Keep in mind that the native
@@ -612,14 +621,14 @@ _g_mount_get_for_mount_path (const char *mount_path,
  *
  * If the return value is not %NULL, the caller must associate the
  * returned #GVolume object with the #GMount. This involves returning
- * it in it's g_mount_get_volume() implementation. The caller must
+ * it in its g_mount_get_volume() implementation. The caller must
  * also listen for the "removed" signal on the returned object
- * and give up it's reference when handling that signal
+ * and give up its reference when handling that signal
  * 
  * Similary, if implementing g_volume_monitor_adopt_orphan_mount(),
  * the implementor must take a reference to @mount and return it in
- * it's g_volume_get_mount() implemented. Also, the implementor must
- * listen for the "unmounted" signal on @mount and give up it's
+ * its g_volume_get_mount() implemented. Also, the implementor must
+ * listen for the "unmounted" signal on @mount and give up its
  * reference upon handling that signal.
  *
  * There are two main use cases for this function.
@@ -627,15 +636,21 @@ _g_mount_get_for_mount_path (const char *mount_path,
  * One is when implementing a user space file system driver that reads
  * blocks of a block device that is already represented by the native
  * volume monitor (for example a CD Audio file system driver). Such
- * a driver will generate it's own #GMount object that needs to be
- * assoicated with the #GVolume object that represents the volume.
+ * a driver will generate its own #GMount object that needs to be
+ * associated with the #GVolume object that represents the volume.
  *
  * The other is for implementing a #GVolumeMonitor whose sole purpose
  * is to return #GVolume objects representing entries in the users
  * "favorite servers" list or similar.
  *
- * Returns: the #GVolume object that is the parent for @mount or %NULL
+ * Returns: (transfer full): the #GVolume object that is the parent for @mount or %NULL
  * if no wants to adopt the #GMount.
+ *
+ * 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. Also see g_mount_is_shadowed(),
+ * g_mount_shadow() and g_mount_unshadow() functions.
  */
 GVolume *
 g_volume_monitor_adopt_orphan_mount (GMount *mount)
@@ -652,9 +667,7 @@ g_volume_monitor_adopt_orphan_mount (GMount *mount)
 
   volume = NULL;
   
-  /* TODO: nasty locking issues because current VM's don't emit signals in idle */
-
-  //G_LOCK (the_volume_monitor);
+  g_rec_mutex_lock (&the_volume_monitor_mutex);
 
   for (l = the_volume_monitor->monitors; l != NULL; l = l->next)
     {
@@ -663,17 +676,13 @@ g_volume_monitor_adopt_orphan_mount (GMount *mount)
 
       if (child_monitor_class->adopt_orphan_mount != NULL)
         {
-          volume = child_monitor_class->adopt_orphan_mount (mount);
+          volume = child_monitor_class->adopt_orphan_mount (mount, child_monitor);
           if (volume != NULL)
             break;
         }
     }
   
-  //G_UNLOCK (the_volume_monitor);
+  g_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return volume;
 }
-
-
-#define __G_UNION_VOLUME_MONITOR_C__
-#include "gioaliasdef.c"