X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgunionvolumemonitor.c;h=4c3049b958014f8cee3db5d5832e188b32e25a05;hb=2e5bd8cf47f9e1559ccc44823a2f321b8ff8c1ea;hp=cc0f081940d1edf280af23429be10f58dd665bec;hpb=7f3280230bc9448a5750fc17a6eabef691ba25f4;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gunionvolumemonitor.c b/gio/gunionvolumemonitor.c index cc0f081..4c3049b 100644 --- a/gio/gunionvolumemonitor.c +++ b/gio/gunionvolumemonitor.c @@ -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. @@ -13,21 +15,20 @@ * 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 . * * Author: Alexander Larsson + * David Zeuthen */ -#include +#include "config.h" #include #include #include "gunionvolumemonitor.h" -#include "gvolumeprivate.h" -#include "giomodule.h" +#include "gmountprivate.h" +#include "giomodule-priv.h" #ifdef G_OS_UNIX #include "gunixvolumemonitor.h" #endif @@ -35,7 +36,6 @@ #include "glibintl.h" -#include "gioalias.h" struct _GUnionVolumeMonitor { GVolumeMonitor parent; @@ -47,44 +47,57 @@ static void g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_mo GVolumeMonitor *child_monitor); +#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 g_union_volume_monitor_finalize (GObject *object) { GUnionVolumeMonitor *monitor; - + GVolumeMonitor *child_monitor; + monitor = G_UNION_VOLUME_MONITOR (object); while (monitor->monitors != NULL) - g_union_volume_monitor_remove_monitor (monitor, - monitor->monitors->data); - - if (G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->finalize) - (*G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->finalize) (object); + { + child_monitor = monitor->monitors->data; + g_union_volume_monitor_remove_monitor (monitor, + child_monitor); + g_object_unref (child_monitor); + } + + 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 * -get_mounted_volumes (GVolumeMonitor *volume_monitor) +get_mounts (GVolumeMonitor *volume_monitor) { GUnionVolumeMonitor *monitor; GVolumeMonitor *child_monitor; @@ -95,17 +108,42 @@ get_mounted_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) { child_monitor = l->data; - res = g_list_concat (res, - g_volume_monitor_get_mounted_volumes (child_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; +} + +static GList * +get_volumes (GVolumeMonitor *volume_monitor) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GList *res; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + res = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + res = g_list_concat (res, g_volume_monitor_get_volumes (child_monitor)); + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); return res; } @@ -122,21 +160,78 @@ 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) { child_monitor = l->data; - res = g_list_concat (res, - g_volume_monitor_get_connected_drives (child_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; } +static GVolume * +get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GVolume *volume; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + volume = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + volume = g_volume_monitor_get_volume_for_uuid (child_monitor, uuid); + if (volume != NULL) + break; + + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return volume; +} + +static GMount * +get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GMount *mount; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + mount = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + mount = g_volume_monitor_get_mount_for_uuid (child_monitor, uuid); + if (mount != NULL) + break; + + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return mount; +} + static void g_union_volume_monitor_class_init (GUnionVolumeMonitorClass *klass) { @@ -146,63 +241,137 @@ g_union_volume_monitor_class_init (GUnionVolumeMonitorClass *klass) gobject_class->finalize = g_union_volume_monitor_finalize; gobject_class->dispose = g_union_volume_monitor_dispose; - monitor_class->get_mounted_volumes = get_mounted_volumes; monitor_class->get_connected_drives = get_connected_drives; + monitor_class->get_volumes = get_volumes; + monitor_class->get_mounts = get_mounts; + monitor_class->get_volume_for_uuid = get_volume_for_uuid; + monitor_class->get_mount_for_uuid = get_mount_for_uuid; } static void -child_volume_mounted (GVolumeMonitor *child_monitor, - GVolume *child_volume, - GUnionVolumeMonitor *union_monitor) +child_volume_added (GVolumeMonitor *child_monitor, + GVolume *child_volume, + GUnionVolumeMonitor *union_monitor) { g_signal_emit_by_name (union_monitor, - "volume_mounted", + "volume-added", child_volume); } static void -child_volume_pre_unmount (GVolumeMonitor *child_monitor, - GVolume *child_volume, - GUnionVolumeMonitor *union_monitor) +child_volume_removed (GVolumeMonitor *child_monitor, + GVolume *child_volume, + GUnionVolumeMonitor *union_monitor) { g_signal_emit_by_name (union_monitor, - "volume_pre_unmount", + "volume-removed", child_volume); } static void -child_volume_unmounted (GVolumeMonitor *child_monitor, - GVolume *child_volume, - GUnionVolumeMonitor *union_monitor) +child_volume_changed (GVolumeMonitor *child_monitor, + GVolume *child_volume, + GUnionVolumeMonitor *union_monitor) { g_signal_emit_by_name (union_monitor, - "volume_unmounted", + "volume-changed", child_volume); } static void -child_drive_connected (GVolumeMonitor *child_monitor, - GDrive *child_drive, - GUnionVolumeMonitor *union_monitor) +child_mount_added (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "mount-added", + child_mount); +} + +static void +child_mount_removed (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) { g_signal_emit_by_name (union_monitor, - "drive_connected", + "mount-removed", + child_mount); +} + +static void +child_mount_pre_unmount (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "mount-pre-unmount", + child_mount); +} + + +static void +child_mount_changed (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "mount-changed", + child_mount); +} + +static void +child_drive_connected (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "drive-connected", child_drive); } static void -child_drive_disconnected (GVolumeMonitor *child_monitor, - GDrive *child_drive, - GUnionVolumeMonitor *union_monitor) +child_drive_disconnected (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) { g_signal_emit_by_name (union_monitor, - "drive_disconnected", + "drive-disconnected", child_drive); } static void +child_drive_changed (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "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); +} + +static void g_union_volume_monitor_add_monitor (GUnionVolumeMonitor *union_monitor, - GVolumeMonitor *volume_monitor) + GVolumeMonitor *volume_monitor) { if (g_list_find (union_monitor->monitors, volume_monitor)) return; @@ -211,16 +380,23 @@ 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_mounted", (GCallback)child_volume_mounted, union_monitor); - g_signal_connect (volume_monitor, "volume_pre_unmount", (GCallback)child_volume_pre_unmount, union_monitor); - g_signal_connect (volume_monitor, "volume_unmounted", (GCallback)child_volume_unmounted, 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, "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 g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor, - GVolumeMonitor *child_monitor) + GVolumeMonitor *child_monitor) { GList *l; @@ -230,102 +406,136 @@ g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor, union_monitor->monitors = g_list_delete_link (union_monitor->monitors, l); - g_signal_handlers_disconnect_by_func (child_monitor, child_volume_mounted, union_monitor); - g_signal_handlers_disconnect_by_func (child_monitor, child_volume_pre_unmount, union_monitor); - g_signal_handlers_disconnect_by_func (child_monitor, child_volume_unmounted, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_volume_added, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_volume_removed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_volume_changed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_added, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_removed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_pre_unmount, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_changed, 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); } -static gpointer -get_default_native_type (gpointer data) +static GType +get_default_native_class (gpointer data) { - GNativeVolumeMonitorClass *klass; - GType *monitors; - guint n_monitors; - GType native_type; - GType *ret = (GType *) data; - int native_prio; - int i; - -#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 (GIO_MODULE_DIR); - - monitors = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_monitors); - native_type = 0; - native_prio = -1; + GNativeVolumeMonitorClass *klass, *native_class, **native_class_out; + const char *use_this; + GIOExtensionPoint *ep; + GIOExtension *extension; + GList *l; + + native_class_out = data; + + use_this = g_getenv ("GIO_USE_VOLUME_MONITOR"); - for (i = 0; i < n_monitors; i++) + /* Ensure vfs in modules loaded */ + _g_io_modules_ensure_loaded (); + + ep = g_io_extension_point_lookup (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME); + + native_class = NULL; + if (use_this) { - klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (monitors[i])); - if (klass->priority > native_prio) - { - native_prio = klass->priority; - native_type = monitors[i]; + extension = g_io_extension_point_get_extension_by_name (ep, use_this); + if (extension) + { + 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); } - - g_free (monitors); - *ret = native_type; - - return NULL; + 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 (void) +/* 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 GType type = G_TYPE_INVALID; + GTypeClass *type_class; - g_once (&once_init, get_default_native_type, &type); + type_class = NULL; + g_once (&once_init, (GThreadFunc)get_default_native_class, &type_class); + + if (type_class == NULL && once_init.retval != GUINT_TO_POINTER(G_TYPE_INVALID)) + type_class = g_type_class_ref ((GType)once_init.retval); - return type; + 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 * @@ -338,13 +548,12 @@ g_union_volume_monitor_new (void) return monitor; } - /** * g_volume_monitor_get: * * 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 * @@ -352,49 +561,128 @@ 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; } +GMount * +_g_mount_get_for_mount_path (const gchar *mount_path, + GCancellable *cancellable) +{ + GNativeVolumeMonitorClass *klass; + GMount *mount; + + klass = get_native_class (); + if (klass == NULL) + return NULL; + + mount = NULL; + + if (klass->get_mount_for_mount_path) + { + g_rec_mutex_lock (&the_volume_monitor_mutex); + mount = klass->get_mount_for_mount_path (mount_path, cancellable); + g_rec_mutex_unlock (&the_volume_monitor_mutex); + } + + /* TODO: How do we know this succeeded? Keep in mind that the native + * volume monitor may fail (e.g. not being able to connect to + * hald). Is the get_mount_for_mount_path() method allowed to + * return NULL? Seems like it is ... probably the method needs + * to take a boolean and write if it succeeds or not.. Messy. + * Very messy. + */ + + g_type_class_unref (klass); + + return mount; +} + /** - * g_volume_get_for_mount_path: - * @mountpoint: a string. + * g_volume_monitor_adopt_orphan_mount: + * @mount: a #GMount object to find a parent for + * + * This function should be called by any #GVolumeMonitor + * implementation when a new #GMount object is created that is not + * associated with a #GVolume object. It must be called just before + * emitting the @mount_added signal. + * + * If the return value is not %NULL, the caller must associate the + * returned #GVolume object with the #GMount. This involves returning + * it in its g_mount_get_volume() implementation. The caller must + * also listen for the "removed" signal on the returned object + * and give up its reference when handling that signal * - * Returns: a #GVolume for given @mountpoint or %NULL. - **/ + * Similary, if implementing g_volume_monitor_adopt_orphan_mount(), + * the implementor must take a reference to @mount and return it in + * 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. + * + * 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 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: (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_get_for_mount_path (const char *mountpoint) +g_volume_monitor_adopt_orphan_mount (GMount *mount) { - GType native_type; - GNativeVolumeMonitorClass *klass; + GVolumeMonitor *child_monitor; + GVolumeMonitorClass *child_monitor_class; GVolume *volume; - - native_type = get_native_type (); + GList *l; - if (native_type == G_TYPE_INVALID) + g_return_val_if_fail (mount != NULL, NULL); + + if (the_volume_monitor == NULL) return NULL; volume = NULL; - klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (native_type)); - if (klass->get_volume_for_mountpoint) - volume = klass->get_volume_for_mountpoint (mountpoint); + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = the_volume_monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + child_monitor_class = G_VOLUME_MONITOR_GET_CLASS (child_monitor); + + if (child_monitor_class->adopt_orphan_mount != NULL) + { + volume = child_monitor_class->adopt_orphan_mount (mount, child_monitor); + if (volume != NULL) + break; + } + } - g_type_class_unref (klass); + g_rec_mutex_unlock (&the_volume_monitor_mutex); return volume; } - -#define __G_UNION_VOLUME_MONITOR_C__ -#include "gioaliasdef.c"