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.
This commit is contained in:
Wim Taymans 2018-01-18 12:47:44 +01:00
parent 155243a27c
commit d50037c2f7
8 changed files with 88 additions and 61 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);