From 1fbd06d85b727a693f86a35e81ae1585861ab15f Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 19 Dec 2007 13:10:22 +0000 Subject: [PATCH] Store the native type as GType, not class so that we can unload it. But 2007-12-19 Alexander Larsson * 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 --- gio/ChangeLog | 7 ++++ gio/gunionvolumemonitor.c | 81 ++++++++++++++++++++++++++++------------------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/gio/ChangeLog b/gio/ChangeLog index d7983b6..d068a9d 100644 --- a/gio/ChangeLog +++ b/gio/ChangeLog @@ -1,3 +1,10 @@ +2007-12-19 Alexander Larsson + + * 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 Introduce g_volume_monitor_adopt_orphan_mount() function. Also diff --git a/gio/gunionvolumemonitor.c b/gio/gunionvolumemonitor.c index b3815d8..772a060 100644 --- a/gio/gunionvolumemonitor.c +++ b/gio/gunionvolumemonitor.c @@ -398,13 +398,12 @@ compare_monitor_type (gconstpointer a, gconstpointer b, gpointer user_data) { - GNativeVolumeMonitorClass *class_a, *class_b; + const 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); + class_a = a; + class_b = b; use_this_monitor = user_data; if (class_a == class_b) @@ -421,16 +420,21 @@ compare_monitor_type (gconstpointer a, return res; } -static GTypeClass * +static GType get_default_native_class (gpointer data) { GNativeVolumeMonitorClass *klass; GType *monitors; guint n_monitors; + GList *l; GTypeClass *native_class; const char *use_this; int i; + GTypeClass **native_class_out; + GList *classes; + native_class_out = data; + use_this = g_getenv ("GIO_USE_VOLUME_MONITOR"); #ifdef G_OS_UNIX @@ -447,43 +451,58 @@ get_default_native_class (gpointer data) 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 */ 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_free (monitors); - g_qsort_with_data (monitors, n_monitors, sizeof (GType), - compare_monitor_type, (gpointer)use_this); + classes = g_list_sort_with_data (classes, + compare_monitor_type, + (gpointer)use_this); 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 ()) { native_class = (GTypeClass *)klass; break; } - g_type_class_unref (klass); + else + 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) + { + *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 () { - 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 @@ -492,16 +511,17 @@ g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor) GVolumeMonitor *monitor; GType *monitors; guint n_monitors; - GType native_type; + GNativeVolumeMonitorClass *native_class; 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_object_unref (monitor); + g_type_class_unref (native_class); } 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, 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); -- 2.7.4