[glib] Add _g_io_module_get_default(), use to simplify other *_get_default()s
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Add _g_io_module_get_default(), use to simplify other *_get_default()s
- Date: Tue, 4 Oct 2011 17:45:42 +0000 (UTC)
commit 1481b7bca3c24149a2970758bc8762e1318f361e
Author: Dan Winship <danw gnome org>
Date: Tue Jun 21 18:21:27 2011 -0400
Add _g_io_module_get_default(), use to simplify other *_get_default()s
Add _g_io_module_get_default(), which implements the
figure-out-the-best-available-module-that-is-actually-usable logic,
and use that to simplify g_proxy_resolver_get_default(),
g_settings_backend_get_default(), g_tls_backend_get_default(), and
g_vfs_get_default().
https://bugzilla.gnome.org/show_bug.cgi?id=620932
gio/giomodule-priv.h | 5 ++
gio/giomodule.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++
gio/gproxyresolver.c | 52 +------------------
gio/gsettingsbackend.c | 63 ++++++++----------------
gio/gtlsbackend.c | 35 +------------
gio/gvfs.c | 53 +-------------------
6 files changed, 161 insertions(+), 174 deletions(-)
---
diff --git a/gio/giomodule-priv.h b/gio/giomodule-priv.h
index a4677b0..b25d305 100644
--- a/gio/giomodule-priv.h
+++ b/gio/giomodule-priv.h
@@ -30,6 +30,11 @@ G_BEGIN_DECLS
void _g_io_modules_ensure_extension_points_registered (void);
void _g_io_modules_ensure_loaded (void);
+typedef gboolean (*GIOModuleVerifyFunc) (gpointer);
+gpointer _g_io_module_get_default (const gchar *extension_point,
+ const gchar *envvar,
+ GIOModuleVerifyFunc verify_func);
+
G_END_DECLS
#endif /* __G_IO_MODULE_PRIV_H__ */
diff --git a/gio/giomodule.c b/gio/giomodule.c
index 2763a98..61638c0 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -630,6 +630,133 @@ g_io_modules_load_all_in_directory (const char *dirname)
return g_io_modules_load_all_in_directory_with_scope (dirname, NULL);
}
+G_LOCK_DEFINE_STATIC (default_modules);
+GHashTable *default_modules;
+
+static gpointer
+try_implementation (GIOExtension *extension,
+ GIOModuleVerifyFunc verify_func)
+{
+ GType type = g_io_extension_get_type (extension);
+ gpointer impl;
+
+ if (g_type_is_a (type, G_TYPE_INITABLE))
+ return g_initable_new (type, NULL, NULL, NULL);
+ else
+ {
+ impl = g_object_new (type, NULL);
+ if (!verify_func || verify_func (impl))
+ return impl;
+
+ g_object_unref (impl);
+ return NULL;
+ }
+}
+
+/**
+ * _g_io_module_get_default:
+ * @extension_point: the name of an extension point
+ * @envvar: (allow-none): the name of an environment variable to
+ * override the default implementation.
+ * @verify_func: (allow-none): a function to call to verify that
+ * a given implementation is usable in the current environment.
+ *
+ * Retrieves the default object implementing @extension_point.
+ *
+ * If @envvar is not %NULL, and the environment variable with that
+ * name is set, then the implementation it specifies will be tried
+ * first. After that, or if @envvar is not set, all other
+ * implementations will be tried in order of decreasing priority.
+ *
+ * If an extension point implementation implements #GInitable, then
+ * that implementation will only be used if it initializes
+ * successfully. Otherwise, if @verify_func is not %NULL, then it will
+ * be called on each candidate implementation after construction, to
+ * check if it is actually usable or not.
+ *
+ * The result is cached after it is generated the first time, and
+ * the function is thread-safe.
+ *
+ * Return value: (transfer none): an object implementing
+ * @extension_point, or %NULL if there are no usable
+ * implementations.
+ */
+gpointer
+_g_io_module_get_default (const gchar *extension_point,
+ const gchar *envvar,
+ GIOModuleVerifyFunc verify_func)
+{
+ const char *use_this;
+ GList *l;
+ GIOExtensionPoint *ep;
+ GIOExtension *extension, *preferred;
+ gpointer impl;
+
+ G_LOCK (default_modules);
+ if (default_modules)
+ {
+ gpointer key;
+
+ if (g_hash_table_lookup_extended (default_modules, extension_point,
+ &key, &impl))
+ {
+ G_UNLOCK (default_modules);
+ return impl;
+ }
+ }
+ else
+ {
+ default_modules = g_hash_table_new (g_str_hash, g_str_equal);
+ }
+
+ _g_io_modules_ensure_loaded ();
+ ep = g_io_extension_point_lookup (extension_point);
+
+ if (!ep)
+ {
+ g_warn_if_reached ();
+ G_UNLOCK (default_modules);
+ return NULL;
+ }
+
+ use_this = envvar ? g_getenv (envvar) : NULL;
+ if (use_this)
+ {
+ preferred = g_io_extension_point_get_extension_by_name (ep, use_this);
+ if (preferred)
+ {
+ impl = try_implementation (preferred, verify_func);
+ if (impl)
+ goto done;
+ }
+ else
+ g_warning ("Can't find module '%s' specified in %s", use_this, envvar);
+ }
+ else
+ preferred = NULL;
+
+ for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
+ {
+ extension = l->data;
+ if (extension == preferred)
+ continue;
+
+ impl = try_implementation (extension, verify_func);
+ if (impl)
+ goto done;
+ }
+
+ impl = NULL;
+
+ done:
+ g_hash_table_insert (default_modules,
+ g_strdup (extension_point),
+ impl ? g_object_ref (impl) : NULL);
+ G_UNLOCK (default_modules);
+
+ return impl;
+}
+
G_LOCK_DEFINE_STATIC (registered_extensions);
G_LOCK_DEFINE_STATIC (loaded_dirs);
diff --git a/gio/gproxyresolver.c b/gio/gproxyresolver.c
index 2bc9733..db2e475 100644
--- a/gio/gproxyresolver.c
+++ b/gio/gproxyresolver.c
@@ -50,52 +50,6 @@ g_proxy_resolver_default_init (GProxyResolverInterface *iface)
{
}
-static gpointer
-get_default_proxy_resolver (gpointer arg)
-{
- const gchar *use_this;
- GProxyResolver *resolver;
- GList *l;
- GIOExtensionPoint *ep;
- GIOExtension *extension;
-
-
- use_this = g_getenv ("GIO_USE_PROXY_RESOLVER");
-
- /* Ensure proxy-resolver modules loaded */
- _g_io_modules_ensure_loaded ();
-
- ep = g_io_extension_point_lookup (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
-
- if (use_this)
- {
- extension = g_io_extension_point_get_extension_by_name (ep, use_this);
- if (extension)
- {
- resolver = g_object_new (g_io_extension_get_type (extension), NULL);
-
- if (g_proxy_resolver_is_supported (resolver))
- return resolver;
-
- g_object_unref (resolver);
- }
- }
-
- for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
- {
- extension = l->data;
-
- resolver = g_object_new (g_io_extension_get_type (extension), NULL);
-
- if (g_proxy_resolver_is_supported (resolver))
- return resolver;
-
- g_object_unref (resolver);
- }
-
- return NULL;
-}
-
/**
* g_proxy_resolver_get_default:
*
@@ -108,9 +62,9 @@ get_default_proxy_resolver (gpointer arg)
GProxyResolver *
g_proxy_resolver_get_default (void)
{
- static GOnce once_init = G_ONCE_INIT;
-
- return g_once (&once_init, get_default_proxy_resolver, NULL);
+ return _g_io_module_get_default (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
+ "GIO_USE_PROXY_RESOLVER",
+ (GIOModuleVerifyFunc)g_proxy_resolver_is_supported);
}
/**
diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
index f824b93..a170241 100644
--- a/gio/gsettingsbackend.c
+++ b/gio/gsettingsbackend.c
@@ -935,6 +935,22 @@ g_settings_backend_create_tree (void)
g_free, g_settings_backend_variant_unref0);
}
+static gboolean
+g_settings_backend_verify (gpointer impl)
+{
+ GSettingsBackend *backend = impl;
+
+ if (strcmp (G_OBJECT_TYPE_NAME (backend), "GMemorySettingsBackend") == 0 &&
+ g_strcmp0 (g_getenv ("GSETTINGS_BACKEND"), "memory") != 0)
+ {
+ g_message ("Using the 'memory' GSettings backend. Your settings "
+ "will not be saved or shared with other applications.");
+ }
+
+ g_settings_has_backend = TRUE;
+ return TRUE;
+}
+
/**
* g_settings_backend_get_default:
* @returns: (transfer full): the default #GSettingsBackend
@@ -950,49 +966,12 @@ g_settings_backend_create_tree (void)
GSettingsBackend *
g_settings_backend_get_default (void)
{
- static gsize backend;
-
- if (g_once_init_enter (&backend))
- {
- GSettingsBackend *instance;
- GIOExtensionPoint *point;
- GIOExtension *extension;
- GType extension_type;
- GList *extensions;
- const gchar *env;
-
- _g_io_modules_ensure_loaded ();
-
- point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
- extension = NULL;
-
- if ((env = getenv ("GSETTINGS_BACKEND")))
- {
- extension = g_io_extension_point_get_extension_by_name (point, env);
-
- if (extension == NULL)
- g_warning ("Can't find GSettings backend '%s' given in "
- "GSETTINGS_BACKEND environment variable", env);
- }
-
- if (extension == NULL)
- {
- extensions = g_io_extension_point_get_extensions (point);
- extension = extensions->data;
-
- if (strcmp (g_io_extension_get_name (extension), "memory") == 0)
- g_message ("Using the 'memory' GSettings backend. Your settings "
- "will not be saved or shared with other applications.");
- }
-
- extension_type = g_io_extension_get_type (extension);
- instance = g_object_new (extension_type, NULL);
- g_settings_has_backend = TRUE;
-
- g_once_init_leave (&backend, (gsize) instance);
- }
+ GSettingsBackend *backend;
- return g_object_ref ((void *) backend);
+ backend = _g_io_module_get_default (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
+ "GSETTINGS_BACKEND",
+ g_settings_backend_verify);
+ return g_object_ref (backend);
}
/*< private >
diff --git a/gio/gtlsbackend.c b/gio/gtlsbackend.c
index 13fff17..2d6913a 100644
--- a/gio/gtlsbackend.c
+++ b/gio/gtlsbackend.c
@@ -80,36 +80,6 @@ g_tls_backend_default_init (GTlsBackendInterface *iface)
{
}
-static gpointer
-get_default_tls_backend (gpointer arg)
-{
- const char *use_this;
- GList *extensions;
- GIOExtensionPoint *ep;
- GIOExtension *extension;
-
- _g_io_modules_ensure_loaded ();
-
- ep = g_io_extension_point_lookup (G_TLS_BACKEND_EXTENSION_POINT_NAME);
-
- use_this = g_getenv ("GIO_USE_TLS");
- if (use_this)
- {
- extension = g_io_extension_point_get_extension_by_name (ep, use_this);
- if (extension)
- return g_object_new (g_io_extension_get_type (extension), NULL);
- }
-
- extensions = g_io_extension_point_get_extensions (ep);
- if (extensions)
- {
- extension = extensions->data;
- return g_object_new (g_io_extension_get_type (extension), NULL);
- }
-
- return NULL;
-}
-
/**
* g_tls_backend_get_default:
*
@@ -122,9 +92,8 @@ get_default_tls_backend (gpointer arg)
GTlsBackend *
g_tls_backend_get_default (void)
{
- static GOnce once_init = G_ONCE_INIT;
-
- return g_once (&once_init, get_default_tls_backend, NULL);
+ return _g_io_module_get_default (G_TLS_BACKEND_EXTENSION_POINT_NAME,
+ "GIO_USE_TLS", NULL);
}
/**
diff --git a/gio/gvfs.c b/gio/gvfs.c
index 697c69b..cbe7f2f 100644
--- a/gio/gvfs.c
+++ b/gio/gvfs.c
@@ -170,53 +170,6 @@ g_vfs_parse_name (GVfs *vfs,
return (* class->parse_name) (vfs, parse_name);
}
-static gpointer
-get_default_vfs (gpointer arg)
-{
- 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 ();
-
- ep = g_io_extension_point_lookup (G_VFS_EXTENSION_POINT_NAME);
-
- 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)
- {
- extension = l->data;
-
- vfs = g_object_new (g_io_extension_get_type (extension), NULL);
-
- if (g_vfs_is_active (vfs))
- return vfs;
-
- g_object_unref (vfs);
- }
-
-
- return NULL;
-}
-
/**
* g_vfs_get_default:
*
@@ -227,9 +180,9 @@ get_default_vfs (gpointer arg)
GVfs *
g_vfs_get_default (void)
{
- static GOnce once_init = G_ONCE_INIT;
-
- return g_once (&once_init, get_default_vfs, NULL);
+ return _g_io_module_get_default (G_VFS_EXTENSION_POINT_NAME,
+ "GIO_USE_VFS",
+ (GIOModuleVerifyFunc)g_vfs_is_active);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]