mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-24 14:36:13 +01:00
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
This commit is contained in:
parent
38d21f6d8a
commit
1481b7bca3
@ -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__ */
|
||||
|
127
gio/giomodule.c
127
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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
GSettingsBackend *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);
|
||||
}
|
||||
|
||||
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 >
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
53
gio/gvfs.c
53
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user