Commit bff9eced authored by Alexander Larsson's avatar Alexander Larsson Committed by Alexander Larsson

Add registration hooks for extension points. Register the gio extension

2008-01-28  Alexander Larsson  <alexl@redhat.com>

        * giomodule.[ch]:
        * gio.symbols:
	Add registration hooks for extension points.
	Register the gio extension points.
	
        * fam/gfamdirectorymonitor.c:
        * fam/gfamfilemonitor.c:
        * glocaldirectorymonitor.[ch]:
        * glocalfilemonitor.[ch]:
        * gnativevolumemonitor.h:
        * gunionvolumemonitor.c:
        * gunixvolumemonitor.c:
        * gvfs.[ch]:
        * gvolumemonitor.h:
        * inotify/ginotifydirectorymonitor.c:
        * inotify/ginotifyfilemonitor.c:
	Use the extension points registration instead
	of g_type_children().


svn path=/trunk/; revision=6399
parent fce0485e
2008-01-28 Alexander Larsson <alexl@redhat.com>
* giomodule.[ch]:
* gio.symbols:
Add registration hooks for extension points.
Register the gio extension points.
* fam/gfamdirectorymonitor.c:
* fam/gfamfilemonitor.c:
* glocaldirectorymonitor.[ch]:
* glocalfilemonitor.[ch]:
* gnativevolumemonitor.h:
* gunionvolumemonitor.c:
* gunixvolumemonitor.c:
* gvfs.[ch]:
* gvolumemonitor.h:
* inotify/ginotifydirectorymonitor.c:
* inotify/ginotifyfilemonitor.c:
Use the extension points registration instead
of g_type_children().
2008-01-28 Matthias Clasen <mclasen@redhat.com>
* gdrive.[hc]:
......
......@@ -112,7 +112,6 @@ g_fam_directory_monitor_class_init (GFamDirectoryMonitorClass* klass)
gobject_class->constructor = g_fam_directory_monitor_constructor;
file_monitor_class->cancel = g_fam_directory_monitor_cancel;
local_directory_monitor_class->prio = 10;
local_directory_monitor_class->mount_notify = FALSE;
local_directory_monitor_class->is_supported = g_fam_directory_monitor_is_supported;
}
......@@ -146,5 +145,9 @@ void
g_fam_directory_monitor_register (GIOModule *module)
{
g_fam_directory_monitor_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME,
G_TYPE_FAM_DIRECTORY_MONITOR,
"fam",
10);
}
......@@ -112,7 +112,6 @@ g_fam_file_monitor_class_init (GFamFileMonitorClass* klass)
gobject_class->constructor = g_fam_file_monitor_constructor;
file_monitor_class->cancel = g_fam_file_monitor_cancel;
local_file_monitor_class->prio = 10;
local_file_monitor_class->is_supported = g_fam_file_monitor_is_supported;
}
......@@ -144,5 +143,9 @@ void
g_fam_file_monitor_register (GIOModule *module)
{
g_fam_file_monitor_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
G_TYPE_FAM_FILE_MONITOR,
"fam",
10);
}
......@@ -486,6 +486,17 @@ g_io_error_from_errno
g_io_module_get_type G_GNUC_CONST
g_io_module_new
g_io_modules_load_all_in_directory
g_io_extension_point_register
g_io_extension_point_lookup
g_io_extension_point_set_required_type
g_io_extension_point_get_required_type
g_io_extension_point_get_extensions
g_io_extension_point_get_extension_by_name
g_io_extension_point_implement
g_io_extension_get_type
g_io_extension_get_name
g_io_extension_get_priority
g_io_extension_ref_class
#endif
#endif
......
......@@ -22,6 +22,8 @@
#include <config.h>
#include <string.h>
#include "giomodule.h"
#include "giomodule-priv.h"
#include "glocalfilemonitor.h"
......@@ -247,20 +249,30 @@ _g_io_modules_ensure_loaded (void)
{
GList *modules, *l;
static gboolean loaded_dirs = FALSE;
int i;
GType *types;
guint n_types;
GQuark private_q, name_q;
GIOExtensionPoint *ep;
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");
ep = g_io_extension_point_register (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR);
ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR);
ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR);
ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR);
ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, G_TYPE_VFS);
modules = g_io_modules_load_all_in_directory (GIO_MODULE_DIR);
/* Initialize types from built-in "modules" */
#if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
......@@ -271,49 +283,7 @@ _g_io_modules_ensure_loaded (void)
_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));
......@@ -323,5 +293,193 @@ _g_io_modules_ensure_loaded (void)
G_UNLOCK (loaded_dirs);
}
struct _GIOExtension {
char *name;
GType type;
gint priority;
};
struct _GIOExtensionPoint {
GType required_type;
char *name;
GList *extensions;
};
static GHashTable *extension_points = NULL;
G_LOCK_DEFINE_STATIC(extension_points);
static void
g_io_extension_point_free (GIOExtensionPoint *ep)
{
g_free (ep->name);
g_free (ep);
}
GIOExtensionPoint *
g_io_extension_point_register (const char *name)
{
GIOExtensionPoint *ep;
G_LOCK (extension_points);
if (extension_points == NULL)
extension_points = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
(GDestroyNotify)g_io_extension_point_free);
if (g_hash_table_lookup (extension_points, name) != NULL)
{
g_warning ("Extension point %s registered multiple times", name);
G_UNLOCK (extension_points);
return NULL;
}
ep = g_new0 (GIOExtensionPoint, 1);
ep->name = g_strdup (name);
g_hash_table_insert (extension_points, ep->name, ep);
G_UNLOCK (extension_points);
return ep;
}
GIOExtensionPoint *
g_io_extension_point_lookup (const char *name)
{
GIOExtensionPoint *ep;
G_LOCK (extension_points);
ep = NULL;
if (extension_points != NULL)
ep = g_hash_table_lookup (extension_points, name);
G_UNLOCK (extension_points);
return ep;
}
void
g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point,
GType type)
{
extension_point->required_type = type;
}
GType
g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point)
{
return extension_point->required_type;
}
GList *
g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point)
{
return extension_point->extensions;
}
GIOExtension *
g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
const char *name)
{
GList *l;
for (l = extension_point->extensions; l != NULL; l = l->next)
{
GIOExtension *e = l->data;
if (e->name != NULL &&
strcmp (e->name, name) == 0)
return e;
}
return NULL;
}
static gint
extension_prio_compare (gconstpointer a,
gconstpointer b)
{
const GIOExtension *extension_a = a, *extension_b = b;
return extension_b->priority - extension_a->priority;
}
GIOExtension *
g_io_extension_point_implement (const char *extension_point_name,
GType type,
const char *extension_name,
gint priority)
{
GIOExtensionPoint *extension_point;
GIOExtension *extension;
GList *l;
g_return_val_if_fail (extension_point_name != NULL, NULL);
extension_point = g_io_extension_point_lookup (extension_point_name);
if (extension_point == NULL)
{
g_warning ("Tried to implement non-registered extension point %s", extension_point_name);
return NULL;
}
if (extension_point->required_type != 0 &&
!g_type_is_a (type, extension_point->required_type))
{
g_warning ("Tried to register an extension of the type %s to extension point %s. "
"Expected type is %s.",
g_type_name (type),
extension_point_name,
g_type_name (extension_point->required_type));
return NULL;
}
/* Its safe to register the same type multiple times */
for (l = extension_point->extensions; l != NULL; l = l->next)
{
extension = l->data;
if (extension->type == type)
return extension;
}
extension = g_slice_new0 (GIOExtension);
extension->type = type;
extension->name = g_strdup (extension_name);
extension->priority = priority;
extension_point->extensions = g_list_insert_sorted (extension_point->extensions,
extension, extension_prio_compare);
return extension;
}
GTypeClass *
g_io_extension_ref_class (GIOExtension *extension)
{
return g_type_class_ref (extension->type);
}
GType
g_io_extension_get_type (GIOExtension *extension)
{
return extension->type;
}
const char *
g_io_extension_get_name (GIOExtension *extension)
{
return extension->name;
}
gint
g_io_extension_get_priority (GIOExtension *extension)
{
return extension->priority;
}
#define __G_IO_MODULE_C__
#include "gioaliasdef.c"
......@@ -47,10 +47,31 @@ G_BEGIN_DECLS
typedef struct _GIOModule GIOModule;
typedef struct _GIOModuleClass GIOModuleClass;
typedef struct _GIOExtensionPoint GIOExtensionPoint;
typedef struct _GIOExtension GIOExtension;
GType g_io_module_get_type (void) G_GNUC_CONST;
GIOModule *g_io_module_new (const gchar *filename);
GList * g_io_modules_load_all_in_directory (const char *dirname);
GList *g_io_modules_load_all_in_directory (const char *dirname);
GIOExtensionPoint *g_io_extension_point_register (const char *extension_point);
GIOExtensionPoint *g_io_extension_point_lookup (const char *extension_point);
void g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point,
GType type);
GType g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point);
GList *g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point);
GIOExtension * g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
const char *name);
GIOExtension * g_io_extension_point_implement (const char *extension_point_name,
GType type,
const char *extension_name,
gint priority);
GType g_io_extension_get_type (GIOExtension *extension);
const char * g_io_extension_get_name (GIOExtension *extension);
gint g_io_extension_get_priority (GIOExtension *extension);
GTypeClass* g_io_extension_ref_class (GIOExtension *extension);
/* API for the modules to implement */
/**
......
......@@ -202,52 +202,27 @@ mounts_changed (GUnixMountMonitor *mount_monitor,
}
}
static gint
_compare_monitor_type_by_prio (gconstpointer _a,
gconstpointer _b,
gpointer user_data)
{
const GType *a = _a, *b = _b;
int prio_a, prio_b;
gint ret;
GQuark private_q;
private_q = g_quark_from_static_string ("gio-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));
ret = prio_b - prio_a;
return ret;
}
static gpointer
get_default_local_directory_monitor (gpointer data)
{
GType *monitor_impls;
guint n_monitor_impls;
gint i;
GLocalDirectoryMonitorClass *chosen_class;
GLocalDirectoryMonitorClass **ret = data;
GIOExtensionPoint *ep;
GList *extensions, *l;
_g_io_modules_ensure_loaded ();
monitor_impls = g_type_children (G_TYPE_LOCAL_DIRECTORY_MONITOR,
&n_monitor_impls);
g_qsort_with_data (monitor_impls,
n_monitor_impls,
sizeof (GType),
_compare_monitor_type_by_prio,
NULL);
ep = g_io_extension_point_lookup (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
extensions = g_io_extension_point_get_extensions (ep);
chosen_class = NULL;
for (i = 0; i < n_monitor_impls; i++)
{
for (l = extensions; l != NULL; l = l->next)
{
GIOExtension *extension = l->data;
GLocalDirectoryMonitorClass *klass;
klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_io_extension_ref_class (extension));
if (klass->is_supported ())
{
......@@ -257,8 +232,6 @@ get_default_local_directory_monitor (gpointer data)
else
g_type_class_unref (klass);
}
g_free (monitor_impls);
if (chosen_class)
{
......
......@@ -36,6 +36,8 @@ G_BEGIN_DECLS
#define G_IS_LOCAL_DIRECTORY_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_DIRECTORY_MONITOR))
#define G_IS_LOCAL_DIRECTORY_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_DIRECTORY_MONITOR))
#define G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME "gio-local-directory-monitor"
typedef struct _GLocalDirectoryMonitor GLocalDirectoryMonitor;
typedef struct _GLocalDirectoryMonitorClass GLocalDirectoryMonitorClass;
......@@ -50,8 +52,6 @@ struct _GLocalDirectoryMonitor
struct _GLocalDirectoryMonitorClass {
GFileMonitorClass parent_class;
gint prio;
char *name; /* Not used atm */
gboolean mount_notify;
gboolean (*is_supported) (void);
};
......
......@@ -129,52 +129,27 @@ static void g_local_file_monitor_class_init (GLocalFileMonitorClass *klass)
G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
}
static gint
_compare_monitor_type_by_prio (gconstpointer _a,
gconstpointer _b,
gpointer user_data)
{
const GType *a = _a, *b = _b;
int prio_a, prio_b;
gint ret;
GQuark private_q;
private_q = g_quark_from_static_string ("gio-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));
ret = prio_b - prio_a;
return ret;
}
static gpointer
get_default_local_file_monitor (gpointer data)
{
GType *monitor_impls;
guint n_monitor_impls;
gint i;
GLocalFileMonitorClass *chosen_class;
GLocalFileMonitorClass **ret = data;
GIOExtensionPoint *ep;
GList *extensions, *l;
_g_io_modules_ensure_loaded ();
monitor_impls = g_type_children (G_TYPE_LOCAL_FILE_MONITOR,
&n_monitor_impls);
g_qsort_with_data (monitor_impls,
n_monitor_impls,
sizeof (GType),
_compare_monitor_type_by_prio,
NULL);
ep = g_io_extension_point_lookup (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
extensions = g_io_extension_point_get_extensions (ep);
chosen_class = NULL;
for (i = 0; i < n_monitor_impls; i++)
{
for (l = extensions; l != NULL; l = l->next)
{
GIOExtension *extension = l->data;
GLocalFileMonitorClass *klass;
klass = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
klass = G_LOCAL_FILE_MONITOR_CLASS (g_io_extension_ref_class (extension));
if (klass->is_supported ())
{
......@@ -184,8 +159,6 @@ get_default_local_file_monitor (gpointer data)
else
g_type_class_unref (klass);
}
g_free (monitor_impls);
if (chosen_class)
{
......
......@@ -34,6 +34,8 @@ G_BEGIN_DECLS
#define G_IS_LOCAL_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_MONITOR))
#define G_IS_LOCAL_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_MONITOR))
#define G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME "gio-local-file-monitor"
typedef struct _GLocalFileMonitor GLocalFileMonitor;
typedef struct _GLocalFileMonitorClass GLocalFileMonitorClass;
......@@ -45,8 +47,6 @@ struct _GLocalFileMonitor
struct _GLocalFileMonitorClass {
GFileMonitorClass parent_class;
gint prio;
char *name; /* Not used atm */
gboolean (*is_supported) (void);
};
......
......@@ -12,6 +12,8 @@ G_BEGIN_DECLS
#define G_IS_NATIVE_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NATIVE_VOLUME_MONITOR))
#define G_IS_NATIVE_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NATIVE_VOLUME_MONITOR))
#define G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME "gio-native-volume-monitor"
typedef struct _GNativeVolumeMonitor GNativeVolumeMonitor;
typedef struct _GNativeVolumeMonitorClass GNativeVolumeMonitorClass;
......
......@@ -390,54 +390,14 @@ g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor,
g_signal_handlers_disconnect_by_func (child_monitor, child_drive_changed, union_monitor);
}
/* Note: This compares in reverse order.
Higher prio -> sort first
*/
static gint
compare_monitor_type (gconstpointer a,
gconstpointer b,
gpointer user_data)
{
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;
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_monitor != NULL &&
strcmp (a_name, use_this_monitor) == 0)
res = -1;
else if (use_this_monitor != NULL &&
strcmp (b_name, use_this_monitor) == 0)
res = 1;
else
res = b_prio - a_prio;
return res;
}
static GType
get_default_native_class (gpointer data)
{
GNativeVolumeMonitorClass *klass, *native_class, **native_class_out;
GType *monitors;
guint n_monitors;
const char *use_this;
int i;
GIOExtensionPoint *ep;
GIOExtension *extension;
GList *l;
native_class_out = data;
......@@ -446,28 +406,37 @@ get_default_native_class (gpointer data)
/* Ensure vfs in modules loaded */
_g_io_modules_ensure_loaded ();
monitors = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_monitors);
g_qsort_with_data (monitors,
n_monitors,
sizeof (GType),
compare_monitor_type,
(gpointer)use_this);
ep = g_io_extension_point_lookup (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
native_class = NULL;
for (i = 0; i < n_monitors; i++)
{
klass = g_type_class_ref (monitors[i]);
if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
if (use_this)
{
extension = g_io_extension_point_get_extension_by_name (ep, use_this);
if (extension)
{
native_class = klass;
break;
klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
native_class = klass;
else
g_type_class_unref (klass);
}
else
g_type_class_unref (klass);
}
g_free (monitors);
if (native_class == NULL)
{
for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
{
extension = l->data;
klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
{
native_class = klass;
break;
}
else
g_type_class_unref (klass);
}
}
if (native_class)
{
......@@ -502,11 +471,11 @@ static void
g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor)
{
GVolumeMonitor *monitor;
GType *monitors;
guint n_monitors;
GNativeVolumeMonitorClass *native_class;
GVolumeMonitorClass *klass;
int i;
GIOExtensionPoint *ep;
GIOExtension *extension;
GList *l;
native_class = get_native_class ();
......@@ -517,26 +486,21 @@ g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor)
g_object_unref (monitor);
g_type_class_unref (native_class);
}
monitors = g_type_children (G_TYPE_VOLUME_MONITOR, &n_monitors);
for (i = 0; i < n_monitors; i++)
{
if (monitors[i] == G_TYPE_UNION_VOLUME_MONITOR ||
g_type_is_a (monitors[i], G_TYPE_NATIVE_VOLUME_MONITOR))
continue;
klass = g_type_class_ref (monitors[i]);
ep = g_io_extension_point_lookup (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
{
extension = l->data;
klass = G_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
if (klass->is_supported == NULL || klass->is_supported())
{
monitor = g_object_new (monitors[i], NULL);
monitor = g_object_new (g_io_extension_get_type (extension), NULL);
g_union_volume_monitor_add_monitor (union_monitor, monitor);
g_object_unref (monitor);