component-loader: activate & register objects through a common code path
Do this in wp_core_load_component() and let the component loaders worry only about creating the object. Also run the main loop in tests while loading components, to ensure that the async operation finishes before continuing execution. GTask makes sure to make the operation async always, by emitting the callback from an idle GSource.
This commit is contained in:
@@ -73,6 +73,49 @@ wp_component_loader_load_finish (WpComponentLoader * self, GAsyncResult * res,
|
|||||||
return WP_COMPONENT_LOADER_GET_IFACE (self)->load_finish (self, res, error);
|
return WP_COMPONENT_LOADER_GET_IFACE (self)->load_finish (self, res, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_object_activated (WpObject * object, GAsyncResult * res, gpointer data)
|
||||||
|
{
|
||||||
|
g_autoptr (GTask) task = G_TASK (data);
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
|
||||||
|
if (!wp_object_activate_finish (object, res, &error)) {
|
||||||
|
g_task_return_error (task, g_steal_pointer (&error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_task_return_pointer (task, g_object_ref (object), g_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_component_loader_load_done (WpComponentLoader * cl, GAsyncResult * res,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
g_autoptr (GTask) task = G_TASK (data);
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
g_autoptr (GObject) o = NULL;
|
||||||
|
WpCore *core = g_task_get_source_object (task);
|
||||||
|
|
||||||
|
o = wp_component_loader_load_finish (cl, res, &error);
|
||||||
|
if (!o) {
|
||||||
|
g_task_return_error (task, g_steal_pointer (&error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_trace_object (cl, "loaded object " WP_OBJECT_FORMAT, WP_OBJECT_ARGS (o));
|
||||||
|
|
||||||
|
/* store object in the registry */
|
||||||
|
wp_registry_register_object (wp_core_get_registry (core), g_object_ref (o));
|
||||||
|
|
||||||
|
if (WP_IS_OBJECT (o)) {
|
||||||
|
/* WpObject needs to be activated */
|
||||||
|
wp_object_activate (WP_OBJECT (o), WP_OBJECT_FEATURES_ALL, NULL,
|
||||||
|
(GAsyncReadyCallback) on_object_activated, g_steal_pointer (&task));
|
||||||
|
} else {
|
||||||
|
g_task_return_pointer (task, g_steal_pointer (&o), g_object_unref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Loads the specified \a component on \a self
|
* \brief Loads the specified \a component on \a self
|
||||||
*
|
*
|
||||||
@@ -98,18 +141,23 @@ wp_core_load_component (WpCore * self, const gchar * component,
|
|||||||
g_autoptr (GTask) task = NULL;
|
g_autoptr (GTask) task = NULL;
|
||||||
g_autoptr (WpComponentLoader) cl = NULL;
|
g_autoptr (WpComponentLoader) cl = NULL;
|
||||||
|
|
||||||
|
task = g_task_new (self, cancellable, callback, data);
|
||||||
|
g_task_set_source_tag (task, wp_core_load_component);
|
||||||
|
|
||||||
/* find a component loader for that type and load the component */
|
/* find a component loader for that type and load the component */
|
||||||
cl = wp_component_loader_find (self, type);
|
cl = wp_component_loader_find (self, type);
|
||||||
if (!cl) {
|
if (!cl) {
|
||||||
task = g_task_new (self, cancellable, callback, data);
|
|
||||||
g_task_return_new_error (task, WP_DOMAIN_LIBRARY,
|
g_task_return_new_error (task, WP_DOMAIN_LIBRARY,
|
||||||
WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||||
"No component loader was found for components of type '%s'", type);
|
"No component loader was found for components of type '%s'", type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wp_debug_object (self, "load '%s', type '%s', loader " WP_OBJECT_FORMAT,
|
||||||
|
component, type, WP_OBJECT_ARGS (cl));
|
||||||
|
|
||||||
wp_component_loader_load (cl, self, component, type, args, cancellable,
|
wp_component_loader_load (cl, self, component, type, args, cancellable,
|
||||||
callback, data);
|
(GAsyncReadyCallback) on_component_loader_load_done, g_object_ref (task));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -127,10 +175,8 @@ GObject *
|
|||||||
wp_core_load_component_finish (WpCore * self, GAsyncResult * res,
|
wp_core_load_component_finish (WpCore * self, GAsyncResult * res,
|
||||||
GError ** error)
|
GError ** error)
|
||||||
{
|
{
|
||||||
g_autoptr (GObject) source = g_async_result_get_source_object (res);
|
g_return_val_if_fail (
|
||||||
|
g_async_result_is_tagged (res, wp_core_load_component), NULL);
|
||||||
|
|
||||||
if (WP_IS_COMPONENT_LOADER (source))
|
|
||||||
return wp_component_loader_load_finish (WP_COMPONENT_LOADER (source), res, error);
|
|
||||||
else
|
|
||||||
return g_task_propagate_pointer (G_TASK (res), error);
|
return g_task_propagate_pointer (G_TASK (res), error);
|
||||||
}
|
}
|
||||||
|
@@ -49,7 +49,7 @@ load_module (WpCore * core, const gchar * module_name, WpSpaJson * args,
|
|||||||
else
|
else
|
||||||
module_path = g_strdup (module_name);
|
module_path = g_strdup (module_name);
|
||||||
|
|
||||||
wp_debug_object (core, "loading %s from %s", module_name, module_path);
|
wp_trace_object (core, "loading %s from %s", module_name, module_path);
|
||||||
|
|
||||||
gmodule = g_module_open (module_path, G_MODULE_BIND_LOCAL);
|
gmodule = g_module_open (module_path, G_MODULE_BIND_LOCAL);
|
||||||
if (!gmodule) {
|
if (!gmodule) {
|
||||||
@@ -69,20 +69,6 @@ load_module (WpCore * core, const gchar * module_name, WpSpaJson * args,
|
|||||||
return ((WpModuleInitFunc) module_init) (core, args, error);
|
return ((WpModuleInitFunc) module_init) (core, args, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_object_activated (WpObject *object, GAsyncResult *res, gpointer data)
|
|
||||||
{
|
|
||||||
g_autoptr (GTask) task = G_TASK (data);
|
|
||||||
g_autoptr (GError) error = NULL;
|
|
||||||
|
|
||||||
if (!wp_object_activate_finish (object, res, &error)) {
|
|
||||||
g_task_return_error (task, g_steal_pointer (&error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_task_return_pointer (task, g_object_ref (object), g_object_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
wp_internal_comp_loader_supports_type (WpComponentLoader * cl,
|
wp_internal_comp_loader_supports_type (WpComponentLoader * cl,
|
||||||
const gchar * type)
|
const gchar * type)
|
||||||
@@ -103,19 +89,10 @@ wp_internal_comp_loader_load (WpComponentLoader * self, WpCore * core,
|
|||||||
|
|
||||||
/* load Module */
|
/* load Module */
|
||||||
o = load_module (core, component, args, &error);
|
o = load_module (core, component, args, &error);
|
||||||
if (!o) {
|
if (o)
|
||||||
|
g_task_return_pointer (task, g_steal_pointer (&o), g_object_unref);
|
||||||
|
else
|
||||||
g_task_return_error (task, g_steal_pointer (&error));
|
g_task_return_error (task, g_steal_pointer (&error));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* store object in the registry */
|
|
||||||
wp_registry_register_object (wp_core_get_registry (core), g_object_ref (o));
|
|
||||||
|
|
||||||
if (WP_IS_OBJECT (o)) {
|
|
||||||
/* WpObject needs to be activated */
|
|
||||||
wp_object_activate (WP_OBJECT (o), WP_OBJECT_FEATURES_ALL, NULL,
|
|
||||||
(GAsyncReadyCallback) on_object_activated, g_object_ref (task));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
|
@@ -160,20 +160,6 @@ find_script (const gchar * script, WpCore *core)
|
|||||||
script, "scripts");
|
script, "scripts");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_script_loaded (WpObject *object, GAsyncResult *res, gpointer data)
|
|
||||||
{
|
|
||||||
g_autoptr (GTask) task = G_TASK (data);
|
|
||||||
g_autoptr (GError) error = NULL;
|
|
||||||
|
|
||||||
if (!wp_object_activate_finish (object, res, &error)) {
|
|
||||||
g_task_return_error (task, g_steal_pointer (&error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_task_return_pointer (task, g_object_ref (object), g_object_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wp_lua_scripting_plugin_load (WpComponentLoader * cl, WpCore * core,
|
wp_lua_scripting_plugin_load (WpComponentLoader * cl, WpCore * core,
|
||||||
const gchar * component, const gchar * type, WpSpaJson * args,
|
const gchar * component, const gchar * type, WpSpaJson * args,
|
||||||
@@ -220,12 +206,7 @@ wp_lua_scripting_plugin_load (WpComponentLoader * cl, WpCore * core,
|
|||||||
"arguments", args,
|
"arguments", args,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* register the script */
|
g_task_return_pointer (task, g_steal_pointer (&script), g_object_unref);
|
||||||
wp_plugin_register (g_object_ref (script));
|
|
||||||
|
|
||||||
/* enable script */
|
|
||||||
wp_object_activate (WP_OBJECT (script), WP_OBJECT_FEATURES_ALL, NULL,
|
|
||||||
(GAsyncReadyCallback) on_script_loaded, g_object_ref (task));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
|
@@ -21,6 +21,8 @@ on_plugin_loaded (WpCore * core, GAsyncResult * res, TestFixture *f)
|
|||||||
o = wp_core_load_component_finish (core, res, &error);
|
o = wp_core_load_component_finish (core, res, &error);
|
||||||
g_assert_nonnull (o);
|
g_assert_nonnull (o);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_main_loop_quit (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -44,6 +46,7 @@ test_si_audio_adapter_setup (TestFixture * f, gconstpointer user_data)
|
|||||||
wp_core_load_component (f->base.core,
|
wp_core_load_component (f->base.core,
|
||||||
"libwireplumber-module-si-audio-adapter", "module", NULL, NULL,
|
"libwireplumber-module-si-audio-adapter", "module", NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_plugin_loaded, f);
|
(GAsyncReadyCallback) on_plugin_loaded, f);
|
||||||
|
g_main_loop_run (f->base.loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,6 +21,8 @@ on_plugin_loaded (WpCore * core, GAsyncResult * res, TestFixture *f)
|
|||||||
o = wp_core_load_component_finish (core, res, &error);
|
o = wp_core_load_component_finish (core, res, &error);
|
||||||
g_assert_nonnull (o);
|
g_assert_nonnull (o);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_main_loop_quit (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -42,11 +44,13 @@ test_si_audio_virtual_setup (TestFixture * f, gconstpointer user_data)
|
|||||||
wp_core_load_component (f->base.core,
|
wp_core_load_component (f->base.core,
|
||||||
"libwireplumber-module-si-audio-adapter", "module", NULL, NULL,
|
"libwireplumber-module-si-audio-adapter", "module", NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_plugin_loaded, f);
|
(GAsyncReadyCallback) on_plugin_loaded, f);
|
||||||
|
g_main_loop_run (f->base.loop);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
wp_core_load_component (f->base.core,
|
wp_core_load_component (f->base.core,
|
||||||
"libwireplumber-module-si-audio-virtual", "module", NULL, NULL,
|
"libwireplumber-module-si-audio-virtual", "module", NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_plugin_loaded, f);
|
(GAsyncReadyCallback) on_plugin_loaded, f);
|
||||||
|
g_main_loop_run (f->base.loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,6 +29,8 @@ on_plugin_loaded (WpCore * core, GAsyncResult * res, TestFixture *f)
|
|||||||
o = wp_core_load_component_finish (core, res, &error);
|
o = wp_core_load_component_finish (core, res, &error);
|
||||||
g_assert_nonnull (o);
|
g_assert_nonnull (o);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_main_loop_quit (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -50,6 +52,7 @@ test_si_node_setup (TestFixture * f, gconstpointer user_data)
|
|||||||
wp_core_load_component (f->base.core,
|
wp_core_load_component (f->base.core,
|
||||||
"libwireplumber-module-si-node", "module", NULL, NULL,
|
"libwireplumber-module-si-node", "module", NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_plugin_loaded, f);
|
(GAsyncReadyCallback) on_plugin_loaded, f);
|
||||||
|
g_main_loop_run (f->base.loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -74,6 +74,8 @@ on_plugin_loaded (WpCore * core, GAsyncResult * res, TestFixture *f)
|
|||||||
o = wp_core_load_component_finish (core, res, &error);
|
o = wp_core_load_component_finish (core, res, &error);
|
||||||
g_assert_nonnull (o);
|
g_assert_nonnull (o);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_main_loop_quit (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -97,10 +99,12 @@ test_si_standard_link_setup (TestFixture * f, gconstpointer user_data)
|
|||||||
wp_core_load_component (f->base.core,
|
wp_core_load_component (f->base.core,
|
||||||
"libwireplumber-module-si-audio-adapter", "module", NULL, NULL,
|
"libwireplumber-module-si-audio-adapter", "module", NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_plugin_loaded, f);
|
(GAsyncReadyCallback) on_plugin_loaded, f);
|
||||||
|
g_main_loop_run (f->base.loop);
|
||||||
|
|
||||||
wp_core_load_component (f->base.core,
|
wp_core_load_component (f->base.core,
|
||||||
"libwireplumber-module-si-standard-link", "module", NULL, NULL,
|
"libwireplumber-module-si-standard-link", "module", NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_plugin_loaded, f);
|
(GAsyncReadyCallback) on_plugin_loaded, f);
|
||||||
|
g_main_loop_run (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_is_spa_lib_installed (&f->base, "audiotestsrc"))
|
if (test_is_spa_lib_installed (&f->base, "audiotestsrc"))
|
||||||
|
@@ -179,7 +179,6 @@ on_plugin_loaded (WpCore * core, GAsyncResult * res, ScriptRunnerFixture *f)
|
|||||||
g_assert_nonnull (o);
|
g_assert_nonnull (o);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
if (WP_IS_PLUGIN (o))
|
|
||||||
g_main_loop_quit (f->base.loop);
|
g_main_loop_quit (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,8 +206,6 @@ load_component (ScriptRunnerFixture *f, const gchar *name, const gchar *type)
|
|||||||
|
|
||||||
wp_core_load_component (f->base.core, component_name, type, NULL, NULL,
|
wp_core_load_component (f->base.core, component_name, type, NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_plugin_loaded, f);
|
(GAsyncReadyCallback) on_plugin_loaded, f);
|
||||||
|
|
||||||
if (!g_str_has_prefix (name, "si"))
|
|
||||||
g_main_loop_run (f->base.loop);
|
g_main_loop_run (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user