From d50037c2f72decc282ae5dee0825628b20f99c44 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 18 Jan 2018 12:47:44 +0100 Subject: [PATCH] global: separate create and register That way we can place the global in the wrapped object before we emit the new_global object and have things work better. --- src/pipewire/client.c | 7 ++-- src/pipewire/core.c | 16 ++++----- src/pipewire/factory.c | 8 +++-- src/pipewire/global.c | 79 +++++++++++++++++++++++++----------------- src/pipewire/global.h | 19 +++++----- src/pipewire/link.c | 6 ++-- src/pipewire/module.c | 7 ++-- src/pipewire/node.c | 7 ++-- 8 files changed, 88 insertions(+), 61 deletions(-) diff --git a/src/pipewire/client.c b/src/pipewire/client.c index 36771e54a..7c95fb116 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -209,10 +209,13 @@ void pw_client_register(struct pw_client *client, pw_log_debug("client %p: register parent %d", client, parent ? parent->id : SPA_ID_INVALID); spa_list_append(&core->client_list, &client->link); - client->global = pw_core_add_global(core, owner, parent, core->type.client, PW_VERSION_CLIENT, + + client->global = pw_global_new(core, core->type.client, PW_VERSION_CLIENT, client_bind_func, client); - if (client->global != NULL) + if (client->global != NULL) { + pw_global_register(client->global, owner, parent); client->info.id = client->global->id; + } } struct pw_core *pw_client_get_core(struct pw_client *client) diff --git a/src/pipewire/core.c b/src/pipewire/core.c index a53d13af6..46311fb93 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -388,15 +388,15 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro this->sc_pagesize = sysconf(_SC_PAGESIZE); - this->global = pw_core_add_global(this, - NULL, - NULL, - this->type.core, - PW_VERSION_CORE, - core_bind_func, - this); - if (this->global != NULL) + this->global = pw_global_new(this, + this->type.core, + PW_VERSION_CORE, + core_bind_func, + this); + if (this->global != NULL) { + pw_global_register(this->global, NULL, NULL); this->info.id = this->global->id; + } return this; diff --git a/src/pipewire/factory.c b/src/pipewire/factory.c index b95b902c5..599d968c5 100644 --- a/src/pipewire/factory.c +++ b/src/pipewire/factory.c @@ -122,10 +122,12 @@ void pw_factory_register(struct pw_factory *factory, { struct pw_core *core = factory->core; spa_list_append(&core->factory_list, &factory->link); - factory->global = pw_core_add_global(core, owner, parent, - core->type.factory, 0, factory_bind_func, factory); - if (factory->global != NULL) + factory->global = pw_global_new(core, + core->type.factory, 0, factory_bind_func, factory); + if (factory->global != NULL) { + pw_global_register(factory->global, owner, parent); factory->info.id = factory->global->id; + } } void *pw_factory_get_user_data(struct pw_factory *factory) diff --git a/src/pipewire/global.c b/src/pipewire/global.c index 42eb75cbe..d9978458c 100644 --- a/src/pipewire/global.c +++ b/src/pipewire/global.c @@ -48,32 +48,26 @@ uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *c return perms; } -/** Create and add a new global to the core +/** Create a new global * - * \param core a core - * \param owner an optional owner of the global + * \param core a core object * \param type the type of the global - * \param n_ifaces number of interfaces - * \param ifaces interface information - * \param object the associated object + * \param version the version of the type * \param bind a function to bind to this global - * \param[out] global a result global - * \return true on success + * \param object the associated object + * \return a result global * - * \memberof pw_core + * \memberof pw_global */ struct pw_global * -pw_core_add_global(struct pw_core *core, - struct pw_client *owner, - struct pw_global *parent, - uint32_t type, - uint32_t version, - pw_bind_func_t bind, - void *object) +pw_global_new(struct pw_core *core, + uint32_t type, + uint32_t version, + pw_bind_func_t bind, + void *object) { struct global_impl *impl; struct pw_global *this; - struct pw_resource *registry; impl = calloc(1, sizeof(struct global_impl)); if (impl == NULL) @@ -82,40 +76,62 @@ pw_core_add_global(struct pw_core *core, this = &impl->this; this->core = core; - this->owner = owner; this->type = type; this->version = version; this->bind = bind; this->object = object; - this->id = pw_map_insert_new(&core->globals, this); + pw_log_debug("global %p: new %s", this, + spa_type_map_get_type(core->type.map, this->type)); + return this; +} + +/** register a global to the core registry + * + * \param global a global to add + * \param owner an optional owner client of the global + * \param parent an optional parent of the global + * \return 0 on success < 0 errno value on failure + * + * \memberof pw_global + */ +int +pw_global_register(struct pw_global *global, + struct pw_client *owner, + struct pw_global *parent) +{ + struct pw_resource *registry; + struct pw_core *core = global->core; + + global->owner = owner; if (owner) parent = owner->global; if (parent == NULL) parent = core->global; if (parent == NULL) - parent = this; - this->parent = parent; + parent = global; + global->parent = parent; - spa_list_append(&core->global_list, &this->link); + global->id = pw_map_insert_new(&core->globals, global); - spa_hook_list_call(&core->listener_list, struct pw_core_events, global_added, this); + spa_list_append(&core->global_list, &global->link); - pw_log_debug("global %p: new %u %s, owner %p", this, this->id, - spa_type_map_get_type(core->type.map, this->type), owner); + spa_hook_list_call(&core->listener_list, struct pw_core_events, global_added, global); + + pw_log_debug("global %p: add %u owner %p parent %p", global, global->id, owner, parent); spa_list_for_each(registry, &core->registry_resource_list, link) { - uint32_t permissions = pw_global_get_permissions(this, registry->client); + uint32_t permissions = pw_global_get_permissions(global, registry->client); if (PW_PERM_IS_R(permissions)) pw_registry_resource_global(registry, - this->id, - this->parent->id, + global->id, + global->parent->id, permissions, - this->type, - this->version); + global->type, + global->version); } - return this; + return 0; } struct pw_core *pw_global_get_core(struct pw_global *global) @@ -123,7 +139,6 @@ struct pw_core *pw_global_get_core(struct pw_global *global) return global->core; } - struct pw_client *pw_global_get_owner(struct pw_global *global) { return global->owner; diff --git a/src/pipewire/global.h b/src/pipewire/global.h index 3300da6b4..b92bc0d90 100644 --- a/src/pipewire/global.h +++ b/src/pipewire/global.h @@ -61,15 +61,18 @@ typedef int (*pw_bind_func_t) (struct pw_global *global, /**< the global to bind uint32_t version, /**< client interface version */ uint32_t id /**< client proxy id */); -/** Add a new global object to the core registry */ +/** Create a new global object */ struct pw_global * -pw_core_add_global(struct pw_core *core, - struct pw_client *owner, - struct pw_global *parent, - uint32_t type, - uint32_t version, - pw_bind_func_t bind, - void *object); +pw_global_new(struct pw_core *core, + uint32_t type, + uint32_t version, + pw_bind_func_t bind, + void *object); + +/** Register a global object to the core registry */ +int pw_global_register(struct pw_global *global, + struct pw_client *owner, + struct pw_global *parent); /** Get the permissions of the global for a given client */ uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *client); diff --git a/src/pipewire/link.c b/src/pipewire/link.c index 1389c7124..272c80d6b 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -1207,10 +1207,12 @@ void pw_link_register(struct pw_link *link, spa_list_append(&core->link_list, &link->link); - link->global = pw_core_add_global(core, owner, parent, core->type.link, PW_VERSION_LINK, + link->global = pw_global_new(core, core->type.link, PW_VERSION_LINK, link_bind_func, link); - if (link->global != NULL) + if (link->global != NULL) { + pw_global_register(link->global, owner, parent); link->info.id = link->global->id; + } input_node = link->input->node; output_node = link->output->node; diff --git a/src/pipewire/module.c b/src/pipewire/module.c index c3abf6ab9..bdecadfeb 100644 --- a/src/pipewire/module.c +++ b/src/pipewire/module.c @@ -219,12 +219,13 @@ struct pw_module *pw_module_load(struct pw_core *core, const char *name, const c this->info.props = NULL; spa_list_append(&core->module_list, &this->link); - this->global = pw_core_add_global(core, NULL, core->global, - core->type.module, PW_VERSION_MODULE, + this->global = pw_global_new(core, core->type.module, PW_VERSION_MODULE, module_bind_func, this); - if (this->global != NULL) + if (this->global != NULL) { + pw_global_register(this->global, NULL, core->global); this->info.id = this->global->id; + } if ((res = init_func(this, args)) < 0) goto init_failed; diff --git a/src/pipewire/node.c b/src/pipewire/node.c index 865255866..a44884383 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -343,11 +343,12 @@ void pw_node_register(struct pw_node *this, pw_loop_invoke(this->data_loop, do_node_add, 1, NULL, 0, false, this); spa_list_append(&core->node_list, &this->link); - this->global = pw_core_add_global(core, owner, parent, - core->type.node, PW_VERSION_NODE, + this->global = pw_global_new(core, core->type.node, PW_VERSION_NODE, node_bind_func, this); - if (this->global != NULL) + if (this->global != NULL) { + pw_global_register(this->global, owner, parent); this->info.id = this->global->id; + } spa_hook_list_call(&this->listener_list, struct pw_node_events, initialized);