From: Alexander Larsson Date: Mon, 28 Jan 2008 19:43:10 +0000 (+0000) Subject: Add registration hooks for extension points. Register the gio extension X-Git-Tag: GLIB_2_15_4~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bff9ecedbbea1a794827f569638365db40c442e6;p=platform%2Fupstream%2Fglib.git Add registration hooks for extension points. Register the gio extension 2008-01-28 Alexander Larsson * 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 --- diff --git a/gio/ChangeLog b/gio/ChangeLog index e29375f..029c088 100644 --- a/gio/ChangeLog +++ b/gio/ChangeLog @@ -1,3 +1,24 @@ +2008-01-28 Alexander Larsson + + * 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 * gdrive.[hc]: diff --git a/gio/fam/gfamdirectorymonitor.c b/gio/fam/gfamdirectorymonitor.c index b947de7..2bf1a71 100644 --- a/gio/fam/gfamdirectorymonitor.c +++ b/gio/fam/gfamdirectorymonitor.c @@ -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); } diff --git a/gio/fam/gfamfilemonitor.c b/gio/fam/gfamfilemonitor.c index 78d3df9..56dafa3 100644 --- a/gio/fam/gfamfilemonitor.c +++ b/gio/fam/gfamfilemonitor.c @@ -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); } diff --git a/gio/gio.symbols b/gio/gio.symbols index 058b510..b2fdae7 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -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 diff --git a/gio/giomodule.c b/gio/giomodule.c index 1b0b388..cee23d6 100644 --- a/gio/giomodule.c +++ b/gio/giomodule.c @@ -22,6 +22,8 @@ #include +#include + #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" diff --git a/gio/giomodule.h b/gio/giomodule.h index bc2bb67..76c27ce 100644 --- a/gio/giomodule.h +++ b/gio/giomodule.h @@ -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 */ /** diff --git a/gio/glocaldirectorymonitor.c b/gio/glocaldirectorymonitor.c index af2bc61..bd59af5 100644 --- a/gio/glocaldirectorymonitor.c +++ b/gio/glocaldirectorymonitor.c @@ -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) { diff --git a/gio/glocaldirectorymonitor.h b/gio/glocaldirectorymonitor.h index 40923e6..c40e5ef 100644 --- a/gio/glocaldirectorymonitor.h +++ b/gio/glocaldirectorymonitor.h @@ -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); }; diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c index 252b9d0..d9517bc 100644 --- a/gio/glocalfilemonitor.c +++ b/gio/glocalfilemonitor.c @@ -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) { diff --git a/gio/glocalfilemonitor.h b/gio/glocalfilemonitor.h index 658310d..81a38a3 100644 --- a/gio/glocalfilemonitor.h +++ b/gio/glocalfilemonitor.h @@ -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); }; diff --git a/gio/gnativevolumemonitor.h b/gio/gnativevolumemonitor.h index f679e74..c4407b8 100644 --- a/gio/gnativevolumemonitor.h +++ b/gio/gnativevolumemonitor.h @@ -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; diff --git a/gio/gunionvolumemonitor.c b/gio/gunionvolumemonitor.c index d6cecee..73acc83 100644 --- a/gio/gunionvolumemonitor.c +++ b/gio/gunionvolumemonitor.c @@ -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); } g_type_class_unref (klass); } - - g_free (monitors); } static GUnionVolumeMonitor * diff --git a/gio/gunixvolumemonitor.c b/gio/gunixvolumemonitor.c index 69b8e36..fcd90fb 100644 --- a/gio/gunixvolumemonitor.c +++ b/gio/gunixvolumemonitor.c @@ -57,7 +57,11 @@ static void update_volumes (GUnixVolumeMonitor *monitor); static void update_mounts (GUnixVolumeMonitor *monitor); #define g_unix_volume_monitor_get_type _g_unix_volume_monitor_get_type -G_DEFINE_TYPE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR); +G_DEFINE_TYPE_WITH_CODE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR, + g_io_extension_point_implement (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "unix", + 0)); static void g_unix_volume_monitor_finalize (GObject *object) @@ -168,8 +172,6 @@ g_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass) 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->get_mount_for_mount_path = get_mount_for_mount_path; } diff --git a/gio/gvfs.c b/gio/gvfs.c index f61c619..67f0d38 100644 --- a/gio/gvfs.c +++ b/gio/gvfs.c @@ -210,36 +210,48 @@ compare_vfs_type (gconstpointer a, static gpointer get_default_vfs (gpointer arg) { - GType *vfs_impls; - int i; - guint n_vfs_impls; const char *use_this; GVfs *vfs; + GList *l; + GIOExtensionPoint *ep; + GIOExtension *extension; + use_this = g_getenv ("GIO_USE_VFS"); /* Ensure vfs in modules loaded */ _g_io_modules_ensure_loaded (); - vfs_impls = g_type_children (G_TYPE_VFS, &n_vfs_impls); + ep = g_io_extension_point_lookup (G_VFS_EXTENSION_POINT_NAME); - g_qsort_with_data (vfs_impls, n_vfs_impls, sizeof (GType), - compare_vfs_type, (gpointer)use_this); - - for (i = 0; i < n_vfs_impls; i++) + if (use_this) + { + extension = g_io_extension_point_get_extension_by_name (ep, use_this); + if (extension) + { + vfs = g_object_new (g_io_extension_get_type (extension), NULL); + + if (g_vfs_is_active (vfs)) + return vfs; + + g_object_unref (vfs); + } + } + + for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next) { - vfs = g_object_new (vfs_impls[i], NULL); + extension = l->data; + + vfs = g_object_new (g_io_extension_get_type (extension), NULL); if (g_vfs_is_active (vfs)) - break; + return vfs; g_object_unref (vfs); - vfs = NULL; } - g_free (vfs_impls); - return vfs; + return NULL; } /** diff --git a/gio/gvfs.h b/gio/gvfs.h index 9400c6f..484b386 100644 --- a/gio/gvfs.h +++ b/gio/gvfs.h @@ -39,6 +39,8 @@ G_BEGIN_DECLS #define G_IS_VFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VFS)) #define G_IS_VFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS)) +#define G_VFS_EXTENSION_POINT_NAME "gio-vfs" + /** * GVfs: * diff --git a/gio/gvolumemonitor.h b/gio/gvolumemonitor.h index 45fb6b7..bfc21b8 100644 --- a/gio/gvolumemonitor.h +++ b/gio/gvolumemonitor.h @@ -42,6 +42,8 @@ G_BEGIN_DECLS #define G_IS_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VOLUME_MONITOR)) #define G_IS_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VOLUME_MONITOR)) +#define G_VOLUME_MONITOR_EXTENSION_POINT_NAME "gio-volume-monitor" + /** * GVolumeMonitor: * @parent_instance: The parent instance. diff --git a/gio/inotify/ginotifydirectorymonitor.c b/gio/inotify/ginotifydirectorymonitor.c index eb90534..945db29 100644 --- a/gio/inotify/ginotifydirectorymonitor.c +++ b/gio/inotify/ginotifydirectorymonitor.c @@ -42,7 +42,11 @@ struct _GInotifyDirectoryMonitor static gboolean g_inotify_directory_monitor_cancel (GFileMonitor* monitor); #define g_inotify_directory_monitor_get_type _g_inotify_directory_monitor_get_type -G_DEFINE_TYPE (GInotifyDirectoryMonitor, g_inotify_directory_monitor, G_TYPE_LOCAL_DIRECTORY_MONITOR) +G_DEFINE_TYPE_WITH_CODE (GInotifyDirectoryMonitor, g_inotify_directory_monitor, G_TYPE_LOCAL_DIRECTORY_MONITOR, + g_io_extension_point_implement (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "inotify", + 20)) static void g_inotify_directory_monitor_finalize (GObject *object) @@ -63,8 +67,8 @@ g_inotify_directory_monitor_finalize (GObject *object) static GObject * g_inotify_directory_monitor_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) + guint n_construct_properties, + GObjectConstructParam *construct_properties) { GObject *obj; GInotifyDirectoryMonitorClass *klass; @@ -116,7 +120,6 @@ g_inotify_directory_monitor_class_init (GInotifyDirectoryMonitorClass* klass) gobject_class->constructor = g_inotify_directory_monitor_constructor; directory_monitor_class->cancel = g_inotify_directory_monitor_cancel; - local_directory_monitor_class->prio = 20; local_directory_monitor_class->mount_notify = TRUE; local_directory_monitor_class->is_supported = g_inotify_directory_monitor_is_supported; } diff --git a/gio/inotify/ginotifyfilemonitor.c b/gio/inotify/ginotifyfilemonitor.c index 7e460f2..eee3eb3 100644 --- a/gio/inotify/ginotifyfilemonitor.c +++ b/gio/inotify/ginotifyfilemonitor.c @@ -44,7 +44,11 @@ struct _GInotifyFileMonitor static gboolean g_inotify_file_monitor_cancel (GFileMonitor* monitor); #define g_inotify_file_monitor_get_type _g_inotify_file_monitor_get_type -G_DEFINE_TYPE (GInotifyFileMonitor, g_inotify_file_monitor, G_TYPE_LOCAL_FILE_MONITOR) +G_DEFINE_TYPE_WITH_CODE (GInotifyFileMonitor, g_inotify_file_monitor, G_TYPE_LOCAL_FILE_MONITOR, + g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "inotify", + 20)) static void g_inotify_file_monitor_finalize (GObject *object) @@ -135,7 +139,6 @@ g_inotify_file_monitor_class_init (GInotifyFileMonitorClass* klass) gobject_class->constructor = g_inotify_file_monitor_constructor; file_monitor_class->cancel = g_inotify_file_monitor_cancel; - local_file_monitor_class->prio = 20; local_file_monitor_class->is_supported = g_inotify_file_monitor_is_supported; }