Add is_supported() to GNativeVolumeMonitorClass so that we can avoid

2007-12-17  Alexander Larsson  <alexl@redhat.com>

        * gnativevolumemonitor.h:
        * gunionvolumemonitor.c:
        * gunixvolumemonitor.c:
	Add is_supported() to GNativeVolumeMonitorClass so
	that we can avoid having to create an object to see
	if the backend is supported at runtime.
	Also add name member and an env var to pick a specific
	volume monitor backend.
	
        * gmountprivate.h:
        * glocalfile.c:
	Add cancellable to _g_mount_get_for_mount_path()
	
        * glocaldirectorymonitor.c:
        * glocalfilemonitor.c:
	Avoid loading and unloading modules while sorting.



svn path=/trunk/; revision=6144
This commit is contained in:
Alexander Larsson 2007-12-17 16:00:33 +00:00 committed by Alexander Larsson
parent feb5258cf9
commit c4e3cfbf40
8 changed files with 118 additions and 63 deletions

View File

@ -1,3 +1,22 @@
2007-12-17 Alexander Larsson <alexl@redhat.com>
* gnativevolumemonitor.h:
* gunionvolumemonitor.c:
* gunixvolumemonitor.c:
Add is_supported() to GNativeVolumeMonitorClass so
that we can avoid having to create an object to see
if the backend is supported at runtime.
Also add name member and an env var to pick a specific
volume monitor backend.
* gmountprivate.h:
* glocalfile.c:
Add cancellable to _g_mount_get_for_mount_path()
* glocaldirectorymonitor.c:
* glocalfilemonitor.c:
Avoid loading and unloading modules while sorting.
2007-12-17 Matthias Clasen <mclasen@redhat.com>
* gio.symbols:

View File

@ -237,6 +237,10 @@ get_default_local_directory_monitor (gpointer data)
chosen_type = G_TYPE_INVALID;
/* Ref all classes once so we don't load/unload them a lot */
for (i = 0; i < n_monitor_impls; i++)
g_type_class_ref (monitor_impls[i]);
g_qsort_with_data (monitor_impls,
n_monitor_impls,
sizeof (GType),
@ -255,6 +259,9 @@ get_default_local_directory_monitor (gpointer data)
g_type_class_unref (klass);
}
for (i = 0; i < n_monitor_impls; i++)
g_type_class_unref (g_type_class_peek (monitor_impls[i]));
g_free (monitor_impls);
*ret = chosen_type;

View File

@ -898,7 +898,7 @@ g_local_file_find_enclosing_mount (GFile *file,
return NULL;
}
mount = _g_mount_get_for_mount_path (mountpoint);
mount = _g_mount_get_for_mount_path (mountpoint, cancellable);
g_free (mountpoint);
if (mount)
return mount;

View File

@ -165,6 +165,10 @@ get_default_local_file_monitor (gpointer data)
chosen_type = G_TYPE_INVALID;
/* Ref all classes once so we don't load/unload them a lot */
for (i = 0; i < n_monitor_impls; i++)
g_type_class_ref (monitor_impls[i]);
g_qsort_with_data (monitor_impls,
n_monitor_impls,
sizeof (GType),
@ -183,6 +187,9 @@ get_default_local_file_monitor (gpointer data)
g_type_class_unref (klass);
}
for (i = 0; i < n_monitor_impls; i++)
g_type_class_unref (g_type_class_peek (monitor_impls[i]));
g_free (monitor_impls);
*ret = chosen_type;

View File

@ -27,7 +27,8 @@
G_BEGIN_DECLS
GMount *_g_mount_get_for_mount_path (const char *mount_path);
GMount *_g_mount_get_for_mount_path (const char *mount_path,
GCancellable *cancellable);
G_END_DECLS

View File

@ -22,9 +22,12 @@ struct _GNativeVolumeMonitor {
struct _GNativeVolumeMonitorClass {
GVolumeMonitorClass parent_class;
GMount * (*get_mount_for_mount_path) (const char *mount_path);
int priority;
char *name;
GMount * (*get_mount_for_mount_path) (const char *mount_path,
GCancellable *cancellable);
gboolean (*is_supported) (void);
};
GType g_native_volume_monitor_get_type (void) G_GNUC_CONST;

View File

@ -390,16 +390,49 @@ g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor,
g_signal_handlers_disconnect_by_func (child_monitor, child_drive_changed, union_monitor);
}
static GType
get_default_native_type_with_exclude (GType type_to_exclude)
/* 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 *
get_default_native_class (gpointer data)
{
GNativeVolumeMonitorClass *klass;
GType *monitors;
guint n_monitors;
GType native_type;
int native_prio;
GTypeClass *native_class;
const char *use_this;
int i;
use_this = g_getenv ("GIO_USE_VOLUME_MONITOR");
#ifdef G_OS_UNIX
/* Ensure GUnixVolumeMonitor type is available */
{
@ -413,55 +446,44 @@ get_default_native_type_with_exclude (GType type_to_exclude)
_g_io_modules_ensure_loaded ();
monitors = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_monitors);
native_type = 0;
native_prio = -1;
/* 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);
native_class = NULL;
for (i = 0; i < n_monitors; i++)
{
if (monitors[i] != type_to_exclude)
{
klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (monitors[i]));
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];
}
g_type_class_unref (klass);
}
if (klass->is_supported ())
{
native_class = (GTypeClass *)klass;
break;
}
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_type;
return native_class;
}
static gpointer
get_default_native_type (gpointer data)
{
GType *ret = (GType *) data;
*ret = get_default_native_type_with_exclude (G_TYPE_INVALID);
return NULL;
}
static GOnce _once_init = G_ONCE_INIT;
static GType _type = G_TYPE_INVALID;
static GType
get_native_type ()
{
static GOnce _once_init = G_ONCE_INIT;
g_once (&_once_init, get_default_native_type, &_type);
return _type;
}
g_once (&_once_init, (GThreadFunc)get_default_native_class, NULL);
static void
update_native_type (GType type)
{
_type = type;
return G_TYPE_FROM_CLASS (_once_init.retval);
}
static void
@ -478,22 +500,8 @@ g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor)
if (native_type != G_TYPE_INVALID)
{
monitor = g_object_new (native_type, NULL);
/* A native file monitor (the hal one if hald isn't running for
* example) may very well fail so handle falling back to the
* native one shipped with gio (e.g. GUnixVolumeMonitor)
*/
if (monitor == NULL)
{
native_type = get_default_native_type_with_exclude (native_type);
monitor = g_object_new (native_type, NULL);
}
if (monitor != NULL)
{
g_union_volume_monitor_add_monitor (union_monitor, monitor);
g_object_unref (monitor);
update_native_type (native_type);
}
g_union_volume_monitor_add_monitor (union_monitor, monitor);
g_object_unref (monitor);
}
monitors = g_type_children (G_TYPE_VOLUME_MONITOR, &n_monitors);
@ -522,7 +530,6 @@ g_union_volume_monitor_new (void)
return monitor;
}
/**
* g_volume_monitor_get:
*
@ -554,11 +561,13 @@ g_volume_monitor_get (void)
/**
* _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 char *mount_path,
GCancellable *cancellable)
{
GType native_type;
GNativeVolumeMonitorClass *klass;
@ -575,7 +584,7 @@ _g_mount_get_for_mount_path (const char *mount_path)
if (klass->get_mount_for_mount_path)
{
G_LOCK (the_volume_monitor);
mount = klass->get_mount_for_mount_path (mount_path);
mount = klass->get_mount_for_mount_path (mount_path, cancellable);
G_UNLOCK (the_volume_monitor);
}

View File

@ -131,8 +131,15 @@ get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
return NULL;
}
static gboolean
is_supported (void)
{
return TRUE;
}
static GMount *
get_mount_for_mount_path (const char *mount_path)
get_mount_for_mount_path (const char *mount_path,
GCancellable *cancellable)
{
GUnixMountEntry *mount_entry;
GUnixMount *mount;
@ -161,6 +168,8 @@ g_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass)
monitor_class->get_mount_for_uuid = get_mount_for_uuid;
native_class->priority = 0;
native_class->name = "unix";
native_class->is_supported = is_supported;
native_class->get_mount_for_mount_path = get_mount_for_mount_path;
}