2007-12-19 Alexander Larsson <alexl@redhat.com>
* giomodule.c:
+ Make g_io_modules_load_all_in_directory not unuse
+ loaded modules so that users of it can do stuff
+ before unloading.
+ Init internal "module" types.
+ Initialize static prio and name for types so that
+ we don't have to load modules to get it.
+
+ * gnativevolumemonitor.h:
+ * gvolumemonitor.h:
+ Move is_supported to parent class so that
+ non-native monitors can avoid being initialized
+ too. (For instance GDaemonVolumeMonitor if we're
+ not using GDaemonVfs.)
+
+ * glocaldirectorymonitor.[ch]:
+ * glocalfilemonitor.[ch]:
+ * gunionvolumemonitor.c:
+ * gunixvolumemonitor.c:
+ * gvfs.c:
+ Find plugins using the static prio+name to
+ avoid unnecessarily loading the modules.
+
+2007-12-19 Alexander Larsson <alexl@redhat.com>
+
+ * giomodule.c:
Remove warnings
2007-12-19 Alexander Larsson <alexl@redhat.com>
#include "giomodule.h"
#include "giomodule-priv.h"
+#include "glocalfilemonitor.h"
+#include "glocaldirectorymonitor.h"
+#include "gnativevolumemonitor.h"
+#include "gvfs.h"
#include "gioalias.h"
* g_io_modules_load_all_in_directory:
* @dirname: pathname for a directory containing modules to load.
*
- * Loads all the modules in the the specified directory.
+ * Loads all the modules in the the specified directory.
*
- * Returns: a list of #GIOModules loaded from the directory
+ * Returns: a list of #GIOModules loaded from the directory,
+ * All the modules are loaded into memory, if you want to
+ * unload them (enabling on-demand loading) you must call
+ * g_type_module_unuse() on all the modules. Free the list
+ * with g_list_free().
**/
GList *
g_io_modules_load_all_in_directory (const char *dirname)
g_free (path);
- g_type_module_unuse (G_TYPE_MODULE (module));
-
modules = g_list_prepend (modules, module);
}
}
G_LOCK_DEFINE_STATIC (loaded_dirs);
+extern GType _g_inotify_directory_monitor_get_type (void);
+extern GType _g_inotify_file_monitor_get_type (void);
+extern GType _g_unix_volume_monitor_get_type (void);
+extern GType _g_local_vfs_get_type (void);
+
void
_g_io_modules_ensure_loaded (void)
{
- GList *modules;
+ GList *modules, *l;
static gboolean loaded_dirs = FALSE;
-
+ int i;
+ GType *types;
+ guint n_types;
+ GQuark private_q, name_q;
+
G_LOCK (loaded_dirs);
if (!loaded_dirs)
{
loaded_dirs = TRUE;
modules = g_io_modules_load_all_in_directory (GIO_MODULE_DIR);
+
+ private_q = g_quark_from_static_string ("gio-prio");
+ name_q = g_quark_from_static_string ("gio-name");
+
+ /* Initialize types from built-in "modules" */
+#if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
+ _g_inotify_directory_monitor_get_type ();
+ _g_inotify_file_monitor_get_type ();
+#endif
+#ifdef G_OS_UNIX
+ _g_unix_volume_monitor_get_type ();
+#endif
+ _g_local_vfs_get_type ();
+
+ /* Copy over all prios to static gtype data so
+ * we can avoid loading the module again
+ */
+
+ types = g_type_children (G_TYPE_LOCAL_FILE_MONITOR, &n_types);
+ for (i = 0; i < n_types; i++)
+ {
+ GLocalFileMonitorClass *klass = g_type_class_ref (types[i]);
+ g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->prio));
+ g_type_class_unref (klass);
+ }
+ g_free (types);
+
+ types = g_type_children (G_TYPE_LOCAL_DIRECTORY_MONITOR, &n_types);
+ for (i = 0; i < n_types; i++)
+ {
+ GLocalDirectoryMonitorClass *klass = g_type_class_ref (types[i]);
+ g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->prio));
+ g_type_class_unref (klass);
+ }
+ g_free (types);
+
+ types = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_types);
+ for (i = 0; i < n_types; i++)
+ {
+ GNativeVolumeMonitorClass *klass = g_type_class_ref (types[i]);
+ g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->priority));
+ g_type_set_qdata (types[i], name_q, g_strdup (klass->name));
+ g_type_class_unref (klass);
+ }
+ g_free (types);
+
+ types = g_type_children (G_TYPE_VFS, &n_types);
+ for (i = 0; i < n_types; i++)
+ {
+ GVfsClass *klass = g_type_class_ref (types[i]);
+ g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->priority));
+ g_type_set_qdata (types[i], name_q, g_strdup (klass->name));
+ g_type_class_unref (klass);
+ }
+ g_free (types);
+
+ for (l = modules; l != NULL; l = l->next)
+ g_type_module_unuse (G_TYPE_MODULE (l->data));
+
+ g_list_free (modules);
}
-
+
G_UNLOCK (loaded_dirs);
}
}
static gint
-_compare_monitor_class_by_prio (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
+_compare_monitor_type_by_prio (gconstpointer _a,
+ gconstpointer _b,
+ gpointer user_data)
{
- GType *type1 = (GType *) a, *type2 = (GType *) b;
- GLocalDirectoryMonitorClass *klass1, *klass2;
+ const GType *a = _a, *b = _b;
+ int prio_a, prio_b;
gint ret;
+ GQuark private_q;
- klass1 = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (*type1));
- klass2 = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (*type2));
+ private_q = g_quark_from_static_string ("gio-prio");
- ret = klass1->prio - klass2->prio;
+ prio_a = GPOINTER_TO_INT (g_type_get_qdata (*a, private_q));
+ prio_b = GPOINTER_TO_INT (g_type_get_qdata (*b, private_q));
- g_type_class_unref (klass1);
- g_type_class_unref (klass2);
+ ret = prio_b - prio_a;
return ret;
}
-extern GType _g_inotify_directory_monitor_get_type (void);
-
static gpointer
get_default_local_directory_monitor (gpointer data)
{
- GType *monitor_impls, chosen_type;
+ GType *monitor_impls;
guint n_monitor_impls;
- GType *ret = (GType *) data;
gint i;
-
-#if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
- /* Register Inotify monitor */
- _g_inotify_directory_monitor_get_type ();
-#endif
+ GLocalDirectoryMonitorClass *chosen_class;
+ GLocalDirectoryMonitorClass **ret = data;
_g_io_modules_ensure_loaded ();
monitor_impls = g_type_children (G_TYPE_LOCAL_DIRECTORY_MONITOR,
&n_monitor_impls);
- 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),
- _compare_monitor_class_by_prio,
+ _compare_monitor_type_by_prio,
NULL);
- for (i = n_monitor_impls - 1; i >= 0 && chosen_type == G_TYPE_INVALID; i--)
+ chosen_class = NULL;
+ for (i = 0; i < n_monitor_impls; i++)
{
GLocalDirectoryMonitorClass *klass;
-
+
klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
-
+
if (klass->is_supported())
- chosen_type = monitor_impls[i];
-
- g_type_class_unref (klass);
+ {
+ chosen_class = klass;
+ break;
+ }
+ else
+ 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;
-
- return NULL;
+
+ if (chosen_class)
+ {
+ *ret = chosen_class;
+ return (gpointer)G_TYPE_FROM_CLASS (chosen_class);
+ }
+ else
+ return (gpointer)G_TYPE_INVALID;
}
/**
GFileMonitorFlags flags)
{
static GOnce once_init = G_ONCE_INIT;
- static GType monitor_type = G_TYPE_INVALID;
-
- g_once (&once_init, get_default_local_directory_monitor, &monitor_type);
-
- if (monitor_type != G_TYPE_INVALID)
- return G_DIRECTORY_MONITOR (g_object_new (monitor_type, "dirname", dirname, NULL));
-
- return NULL;
+ GTypeClass *type_class;
+ GDirectoryMonitor *monitor;
+ GType type;
+
+ type_class = NULL;
+ g_once (&once_init, get_default_local_directory_monitor, &type_class);
+ type = (GType)once_init.retval;
+
+ monitor = NULL;
+ if (type != G_TYPE_INVALID)
+ monitor = G_DIRECTORY_MONITOR (g_object_new (type, "dirname", dirname, NULL));
+
+ /* This is non-null on first pass here. Unref the class now.
+ * This is to avoid unloading the module and then loading it
+ * again which would happen if we unrefed the class
+ * before creating the monitor.
+ */
+
+ if (type_class)
+ g_type_class_unref (type_class);
+
+ return monitor;
}
static gboolean
struct _GLocalDirectoryMonitorClass {
GDirectoryMonitorClass parent_class;
gint prio;
+ char *name; /* Not used atm */
gboolean mount_notify;
gboolean (*is_supported) (void);
};
}
static gint
-_compare_monitor_class_by_prio (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
+_compare_monitor_type_by_prio (gconstpointer _a,
+ gconstpointer _b,
+ gpointer user_data)
{
- GType *type1 = (GType *) a, *type2 = (GType *) b;
- GLocalFileMonitorClass *klass1, *klass2;
+ const GType *a = _a, *b = _b;
+ int prio_a, prio_b;
gint ret;
+ GQuark private_q;
- klass1 = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (*type1));
- klass2 = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (*type2));
+ private_q = g_quark_from_static_string ("gio-prio");
- ret = klass1->prio - klass2->prio;
+ prio_a = GPOINTER_TO_INT (g_type_get_qdata (*a, private_q));
+ prio_b = GPOINTER_TO_INT (g_type_get_qdata (*b, private_q));
- g_type_class_unref (klass1);
- g_type_class_unref (klass2);
+ ret = prio_b - prio_a;
return ret;
}
-extern GType _g_inotify_file_monitor_get_type (void);
-
static gpointer
get_default_local_file_monitor (gpointer data)
{
- GType *monitor_impls, chosen_type;
+ GType *monitor_impls;
guint n_monitor_impls;
gint i;
- GType *ret = (GType *) data;
-
-#if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
- /* Register Inotify monitor */
- _g_inotify_file_monitor_get_type ();
-#endif
+ GLocalFileMonitorClass *chosen_class;
+ GLocalFileMonitorClass **ret = data;
_g_io_modules_ensure_loaded ();
monitor_impls = g_type_children (G_TYPE_LOCAL_FILE_MONITOR,
&n_monitor_impls);
- 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),
- _compare_monitor_class_by_prio,
+ _compare_monitor_type_by_prio,
NULL);
- for (i = n_monitor_impls - 1; i >= 0 && chosen_type == G_TYPE_INVALID; i--)
+ chosen_class = NULL;
+ for (i = 0; i < n_monitor_impls; i++)
{
GLocalFileMonitorClass *klass;
-
+
klass = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
-
+
if (klass->is_supported())
- chosen_type = monitor_impls[i];
-
- g_type_class_unref (klass);
+ {
+ chosen_class = klass;
+ break;
+ }
+ else
+ 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;
-
- return NULL;
+
+ if (chosen_class)
+ {
+ *ret = chosen_class;
+ return (gpointer)G_TYPE_FROM_CLASS (chosen_class);
+ }
+ else
+ return (gpointer)G_TYPE_INVALID;
}
/**
GFileMonitorFlags flags)
{
static GOnce once_init = G_ONCE_INIT;
- static GType monitor_type = G_TYPE_INVALID;
-
- g_once (&once_init, get_default_local_file_monitor, &monitor_type);
-
- if (monitor_type != G_TYPE_INVALID)
- return G_FILE_MONITOR (g_object_new (monitor_type, "filename", pathname, NULL));
-
- return NULL;
+ GTypeClass *type_class;
+ GFileMonitor *monitor;
+ GType type;
+
+ type_class = NULL;
+ g_once (&once_init, get_default_local_file_monitor, &type_class);
+ type = (GType)once_init.retval;
+
+ monitor = NULL;
+ if (type != G_TYPE_INVALID)
+ monitor = G_FILE_MONITOR (g_object_new (type, "filename", pathname, NULL));
+
+ /* This is non-null on first pass here. Unref the class now.
+ * This is to avoid unloading the module and then loading it
+ * again which would happen if we unrefed the class
+ * before creating the monitor.
+ */
+
+ if (type_class)
+ g_type_class_unref (type_class);
+
+ return monitor;
}
#define __G_LOCAL_FILE_MONITOR_C__
struct _GLocalFileMonitorClass {
GFileMonitorClass parent_class;
gint prio;
+ char *name; /* Not used atm */
gboolean (*is_supported) (void);
};
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;
gconstpointer b,
gpointer user_data)
{
- const GNativeVolumeMonitorClass *class_a, *class_b;
+ GType a_type, b_type;
+ char *a_name, *b_name;
+ int a_prio, b_prio;
gint res;
const char *use_this_monitor;
+ GQuark private_q, name_q;
- class_a = a;
- class_b = b;
+ private_q = g_quark_from_static_string ("gio-prio");
+ name_q = g_quark_from_static_string ("gio-name");
+
use_this_monitor = user_data;
-
- if (class_a == class_b)
+ a_type = *(GType *)a;
+ b_type = *(GType *)b;
+ a_prio = GPOINTER_TO_INT (g_type_get_qdata (a_type, private_q));
+ a_name = g_type_get_qdata (a_type, name_q);
+ b_prio = GPOINTER_TO_INT (g_type_get_qdata (b_type, private_q));
+ b_name = g_type_get_qdata (b_type, name_q);
+
+ if (a_type == b_type)
res = 0;
else if (use_this_monitor != NULL &&
- strcmp (class_a->name, use_this_monitor) == 0)
+ strcmp (a_name, use_this_monitor) == 0)
res = -1;
else if (use_this_monitor != NULL &&
- strcmp (class_b->name, use_this_monitor) == 0)
+ strcmp (b_name, use_this_monitor) == 0)
res = 1;
else
- res = class_b->priority - class_a->priority;
+ res = b_prio - a_prio;
return res;
}
static GType
get_default_native_class (gpointer data)
{
- GNativeVolumeMonitorClass *klass;
+ GNativeVolumeMonitorClass *klass, *native_class, **native_class_out;
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
- /* 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 ();
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++)
- classes = g_list_prepend (classes, g_type_class_ref (monitors[i]));
-
- g_free (monitors);
-
- classes = g_list_sort_with_data (classes,
- compare_monitor_type,
- (gpointer)use_this);
+ g_qsort_with_data (monitors,
+ n_monitors,
+ sizeof (GType),
+ compare_monitor_type,
+ (gpointer)use_this);
native_class = NULL;
- for (l = classes; l != NULL; l = l->next)
- {
- klass = l->data;
-
- if (klass->is_supported ())
+ for (i = 0; i < n_monitors; i++)
+ {
+ klass = g_type_class_ref (monitors[i]);
+ if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
{
- native_class = (GTypeClass *)klass;
+ native_class = klass;
break;
}
else
g_type_class_unref (klass);
}
+ g_free (monitors);
+
if (native_class)
{
*native_class_out = native_class;
GType *monitors;
guint n_monitors;
GNativeVolumeMonitorClass *native_class;
+ GVolumeMonitorClass *klass;
int i;
native_class = get_native_class ();
if (monitors[i] == G_TYPE_UNION_VOLUME_MONITOR ||
g_type_is_a (monitors[i], G_TYPE_NATIVE_VOLUME_MONITOR))
continue;
-
- monitor = g_object_new (monitors[i], NULL);
- g_union_volume_monitor_add_monitor (union_monitor, monitor);
- g_object_unref (monitor);
+
+ klass = g_type_class_ref (monitors[i]);
+ if (klass->is_supported == NULL || klass->is_supported())
+ {
+ monitor = g_object_new (monitors[i], NULL);
+ g_union_volume_monitor_add_monitor (union_monitor, monitor);
+ g_object_unref (monitor);
+ }
+ g_type_class_unref (klass);
}
g_free (monitors);
monitor_class->get_connected_drives = get_connected_drives;
monitor_class->get_volume_for_uuid = get_volume_for_uuid;
monitor_class->get_mount_for_uuid = get_mount_for_uuid;
+ monitor_class->is_supported = is_supported;
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;
}
gconstpointer b,
gpointer user_data)
{
- GVfsClass *class_a, *class_b;
+ GType a_type, b_type;
+ char *a_name, *b_name;
+ int a_prio, b_prio;
gint res;
- const char *use_this_vfs;
-
- class_a = g_type_class_ref (*(GType *)a);
- class_b = g_type_class_ref (*(GType *)b);
- use_this_vfs = user_data;
+ const char *use_this_monitor;
+ GQuark private_q, name_q;
- if (class_a == class_b)
+ private_q = g_quark_from_static_string ("gio-prio");
+ name_q = g_quark_from_static_string ("gio-name");
+
+ use_this_monitor = user_data;
+ a_type = *(GType *)a;
+ b_type = *(GType *)b;
+ a_prio = GPOINTER_TO_INT (g_type_get_qdata (a_type, private_q));
+ a_name = g_type_get_qdata (a_type, name_q);
+ b_prio = GPOINTER_TO_INT (g_type_get_qdata (b_type, private_q));
+ b_name = g_type_get_qdata (b_type, name_q);
+
+ if (a_type == b_type)
res = 0;
- else if (use_this_vfs != NULL &&
- strcmp (class_a->name, use_this_vfs) == 0)
+ else if (use_this_monitor != NULL &&
+ strcmp (a_name, use_this_monitor) == 0)
res = -1;
- else if (use_this_vfs != NULL &&
- strcmp (class_b->name, use_this_vfs) == 0)
+ else if (use_this_monitor != NULL &&
+ strcmp (b_name, use_this_monitor) == 0)
res = 1;
else
- res = class_b->priority - class_a->priority;
-
- g_type_class_unref (class_a);
- g_type_class_unref (class_b);
+ res = b_prio - a_prio;
return res;
}
-
static gpointer
get_default_vfs (gpointer arg)
{
guint n_vfs_impls;
const char *use_this;
GVfs *vfs;
- GType (*casted_get_type)(void);
use_this = g_getenv ("GIO_USE_VFS");
- /* Ensure GLocalVfs type is available
- the cast is required to avoid any G_GNUC_CONST optimizations */
- casted_get_type = _g_local_vfs_get_type;
- local_type = casted_get_type ();
-
/* Ensure vfs in modules loaded */
_g_io_modules_ensure_loaded ();
/* Vtable */
+ gboolean (*is_supported) (void);
+
GList * (*get_connected_drives) (GVolumeMonitor *volume_monitor);
GList * (*get_volumes) (GVolumeMonitor *volume_monitor);
GList * (*get_mounts) (GVolumeMonitor *volume_monitor);
GVolume * (*adopt_orphan_mount) (GMount *mount);
+
/*< private >*/
/* Padding for future expansion */
void (*_g_reserved1) (void);