+/* -*- 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>
#include <glib.h>
#include "gunionvolumemonitor.h"
-#include "gvolumeprivate.h"
-#include "giomodule.h"
+#include "gmountprivate.h"
+#include "giomodule-priv.h"
#ifdef G_OS_UNIX
#include "gunixvolumemonitor.h"
#endif
#include "glibintl.h"
-#include "gioalias.h"
struct _GUnionVolumeMonitor {
GVolumeMonitor parent;
#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;
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;
}
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)
{
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_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,
+ "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",
+ "drive-connected",
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)
{
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
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;
- for (i = 0; i < n_monitors; i++)
+ use_this = g_getenv ("GIO_USE_VOLUME_MONITOR");
+
+ /* 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;
+
+ type_class = NULL;
+ g_once (&once_init, (GThreadFunc)get_default_native_class, &type_class);
- g_once (&once_init, get_default_native_type, &type);
+ 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 *
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 *
{
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"