Store the native type as GType, not class so that we can unload it. But

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

        * gunionvolumemonitor.c:
	Store the native type as GType, not class so that
	we can unload it. But still avoid unnecessarily
	unload modules.


svn path=/trunk/; revision=6156
This commit is contained in:
Alexander Larsson 2007-12-19 13:10:22 +00:00 committed by Alexander Larsson
parent dfe3409c92
commit 1fbd06d85b
2 changed files with 56 additions and 32 deletions

View File

@ -1,3 +1,10 @@
2007-12-19 Alexander Larsson <alexl@redhat.com>
* gunionvolumemonitor.c:
Store the native type as GType, not class so that
we can unload it. But still avoid unnecessarily
unload modules.
2007-12-19 David Zeuthen <davidz@redhat.com> 2007-12-19 David Zeuthen <davidz@redhat.com>
Introduce g_volume_monitor_adopt_orphan_mount() function. Also Introduce g_volume_monitor_adopt_orphan_mount() function. Also

View File

@ -398,13 +398,12 @@ compare_monitor_type (gconstpointer a,
gconstpointer b, gconstpointer b,
gpointer user_data) gpointer user_data)
{ {
GNativeVolumeMonitorClass *class_a, *class_b; const GNativeVolumeMonitorClass *class_a, *class_b;
gint res; gint res;
const char *use_this_monitor; const char *use_this_monitor;
/* We ref:ed all the classes, so the peek is safe */ class_a = a;
class_a = g_type_class_peek (*(GType *)a); class_b = b;
class_b = g_type_class_peek (*(GType *)b);
use_this_monitor = user_data; use_this_monitor = user_data;
if (class_a == class_b) if (class_a == class_b)
@ -421,15 +420,20 @@ compare_monitor_type (gconstpointer a,
return res; return res;
} }
static GTypeClass * static GType
get_default_native_class (gpointer data) get_default_native_class (gpointer data)
{ {
GNativeVolumeMonitorClass *klass; GNativeVolumeMonitorClass *klass;
GType *monitors; GType *monitors;
guint n_monitors; guint n_monitors;
GList *l;
GTypeClass *native_class; GTypeClass *native_class;
const char *use_this; const char *use_this;
int i; int i;
GTypeClass **native_class_out;
GList *classes;
native_class_out = data;
use_this = g_getenv ("GIO_USE_VOLUME_MONITOR"); use_this = g_getenv ("GIO_USE_VOLUME_MONITOR");
@ -447,43 +451,58 @@ get_default_native_class (gpointer data)
monitors = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_monitors); monitors = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_monitors);
classes = NULL;
/* Ref all classes once so we don't load/unload them a lot */ /* Ref all classes once so we don't load/unload them a lot */
for (i = 0; i < n_monitors; i++) for (i = 0; i < n_monitors; i++)
g_type_class_ref (monitors[i]); classes = g_list_prepend (classes, g_type_class_ref (monitors[i]));
g_qsort_with_data (monitors, n_monitors, sizeof (GType), g_free (monitors);
compare_monitor_type, (gpointer)use_this);
classes = g_list_sort_with_data (classes,
compare_monitor_type,
(gpointer)use_this);
native_class = NULL; native_class = NULL;
for (i = 0; i < n_monitors; i++) for (l = classes; l != NULL; l = l->next)
{ {
klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (monitors[i])); klass = l->data;
if (klass->is_supported ()) if (klass->is_supported ())
{ {
native_class = (GTypeClass *)klass; native_class = (GTypeClass *)klass;
break; break;
} }
else
g_type_class_unref (klass); g_type_class_unref (klass);
} }
for (i = 0; i < n_monitors; i++) if (native_class)
g_type_class_unref (g_type_class_peek (monitors[i])); {
*native_class_out = native_class;
g_free (monitors); return G_TYPE_FROM_CLASS (native_class);
}
return native_class; else
return G_TYPE_INVALID;
} }
/* We return the class, with a ref taken.
static GType * This way we avoid unloading the class/module
get_native_type () * between selecting the type and creating the
* instance on the first call.
*/
static GNativeVolumeMonitorClass *
get_native_class ()
{ {
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 != G_TYPE_INVALID)
type_class = g_type_class_ref ((GType)once_init.retval);
return (GNativeVolumeMonitorClass *)type_class;
} }
static void static void
@ -492,16 +511,17 @@ g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor)
GVolumeMonitor *monitor; GVolumeMonitor *monitor;
GType *monitors; GType *monitors;
guint n_monitors; guint n_monitors;
GType native_type; GNativeVolumeMonitorClass *native_class;
int i; int i;
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_union_volume_monitor_add_monitor (union_monitor, monitor);
g_object_unref (monitor); g_object_unref (monitor);
g_type_class_unref (native_class);
} }
monitors = g_type_children (G_TYPE_VOLUME_MONITOR, &n_monitors); monitors = g_type_children (G_TYPE_VOLUME_MONITOR, &n_monitors);
@ -569,18 +589,15 @@ GMount *
_g_mount_get_for_mount_path (const char *mount_path, _g_mount_get_for_mount_path (const char *mount_path,
GCancellable *cancellable) GCancellable *cancellable)
{ {
GType native_type;
GNativeVolumeMonitorClass *klass; GNativeVolumeMonitorClass *klass;
GMount *mount; GMount *mount;
native_type = get_native_type (); klass = get_native_class ();
if (klass == NULL)
if (native_type == G_TYPE_INVALID)
return NULL; return NULL;
mount = NULL; mount = NULL;
klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (native_type));
if (klass->get_mount_for_mount_path) if (klass->get_mount_for_mount_path)
{ {
G_LOCK (the_volume_monitor); G_LOCK (the_volume_monitor);