mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
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:
parent
dfe3409c92
commit
1fbd06d85b
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user