mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
Make sure we bind before registering the global
Bind to the resource in create_object before we register the global. This ensure a client gets to see the resource global id associated with the resource before it appears in the registry, which makes it easier to patch the local proxy to the global object.
This commit is contained in:
parent
b7c5e00697
commit
8acae9db7d
3 changed files with 88 additions and 58 deletions
|
|
@ -66,7 +66,9 @@ struct node_data {
|
|||
struct pw_node *adapter;
|
||||
struct pw_node *slave;
|
||||
struct spa_hook adapter_listener;
|
||||
struct pw_resource *resource;
|
||||
struct spa_hook resource_listener;
|
||||
uint32_t new_id;
|
||||
};
|
||||
|
||||
static void resource_destroy(void *data)
|
||||
|
|
@ -96,10 +98,42 @@ static void node_free(void *data)
|
|||
pw_node_destroy(nd->slave);
|
||||
}
|
||||
|
||||
static void node_initialized(void *data)
|
||||
{
|
||||
struct node_data *nd = data;
|
||||
struct pw_client *client;
|
||||
struct pw_resource *bound_resource;
|
||||
struct pw_global *global;
|
||||
int res;
|
||||
|
||||
if (nd->resource == NULL)
|
||||
return;
|
||||
|
||||
client = pw_resource_get_client(nd->resource);
|
||||
global = pw_node_get_global(nd->adapter);
|
||||
|
||||
res = pw_global_bind(global, client,
|
||||
PW_PERM_RWX, PW_VERSION_NODE_PROXY, nd->new_id);
|
||||
if (res < 0)
|
||||
goto error_bind;
|
||||
|
||||
if ((bound_resource = pw_client_find_resource(client, nd->new_id)) == NULL)
|
||||
goto error_bind;
|
||||
|
||||
pw_resource_add_listener(bound_resource, &nd->resource_listener, &resource_events, nd);
|
||||
return;
|
||||
|
||||
error_bind:
|
||||
pw_resource_error(nd->resource, res, "can't bind adapter node");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static const struct pw_node_events node_events = {
|
||||
PW_VERSION_NODE_EVENTS,
|
||||
.destroy = node_destroy,
|
||||
.free = node_free,
|
||||
.initialized = node_initialized,
|
||||
};
|
||||
|
||||
static void *create_object(void *_data,
|
||||
|
|
@ -167,26 +201,14 @@ static void *create_object(void *_data,
|
|||
nd->data = d;
|
||||
nd->adapter = adapter;
|
||||
nd->slave = slave;
|
||||
nd->resource = resource;
|
||||
nd->new_id = new_id;
|
||||
spa_list_append(&d->node_list, &nd->link);
|
||||
|
||||
pw_node_add_listener(adapter, &nd->adapter_listener, &node_events, nd);
|
||||
|
||||
pw_node_register(adapter, NULL);
|
||||
|
||||
if (client) {
|
||||
struct pw_resource *bound_resource;
|
||||
|
||||
res = pw_global_bind(pw_node_get_global(adapter), client,
|
||||
PW_PERM_RWX, PW_VERSION_NODE_PROXY, new_id);
|
||||
if (res < 0)
|
||||
goto error_bind;
|
||||
|
||||
if ((bound_resource = pw_client_find_resource(client, new_id)) == NULL)
|
||||
goto error_bind;
|
||||
|
||||
pw_resource_add_listener(bound_resource, &nd->resource_listener, &resource_events, nd);
|
||||
}
|
||||
|
||||
pw_node_set_active(adapter, true);
|
||||
|
||||
return adapter;
|
||||
|
|
@ -209,10 +231,6 @@ error_usage:
|
|||
if (resource)
|
||||
pw_resource_error(resource, res, "usage: "ADAPTER_USAGE);
|
||||
goto error_cleanup;
|
||||
error_bind:
|
||||
if (resource)
|
||||
pw_resource_error(resource, res, "can't bind adapter node");
|
||||
goto error_cleanup;
|
||||
error_cleanup:
|
||||
if (properties)
|
||||
pw_properties_free(properties);
|
||||
|
|
|
|||
|
|
@ -61,10 +61,16 @@ struct link_data {
|
|||
struct spa_list l;
|
||||
struct pw_link *link;
|
||||
struct spa_hook link_listener;
|
||||
|
||||
struct pw_resource *resource;
|
||||
struct spa_hook resource_listener;
|
||||
|
||||
struct pw_global *global;
|
||||
struct spa_hook global_listener;
|
||||
|
||||
struct pw_resource *factory_resource;
|
||||
uint32_t new_id;
|
||||
bool linger;
|
||||
};
|
||||
|
||||
static void resource_destroy(void *data)
|
||||
|
|
@ -81,21 +87,6 @@ static const struct pw_resource_events resource_events = {
|
|||
.destroy = resource_destroy
|
||||
};
|
||||
|
||||
static void link_destroy(void *data)
|
||||
{
|
||||
struct link_data *ld = data;
|
||||
spa_list_remove(&ld->l);
|
||||
if (ld->global)
|
||||
spa_hook_remove(&ld->global_listener);
|
||||
if (ld->resource)
|
||||
spa_hook_remove(&ld->resource_listener);
|
||||
}
|
||||
|
||||
static const struct pw_link_events link_events = {
|
||||
PW_VERSION_LINK_EVENTS,
|
||||
.destroy = link_destroy
|
||||
};
|
||||
|
||||
static void global_destroy(void *data)
|
||||
{
|
||||
struct link_data *ld = data;
|
||||
|
|
@ -108,6 +99,49 @@ static const struct pw_global_events global_events = {
|
|||
.destroy = global_destroy
|
||||
};
|
||||
|
||||
static void link_destroy(void *data)
|
||||
{
|
||||
struct link_data *ld = data;
|
||||
spa_list_remove(&ld->l);
|
||||
if (ld->global)
|
||||
spa_hook_remove(&ld->global_listener);
|
||||
if (ld->resource)
|
||||
spa_hook_remove(&ld->resource_listener);
|
||||
}
|
||||
|
||||
static void link_initialized(void *data)
|
||||
{
|
||||
struct link_data *ld = data;
|
||||
struct pw_client *client = pw_resource_get_client(ld->factory_resource);
|
||||
int res;
|
||||
|
||||
ld->global = pw_link_get_global(ld->link);
|
||||
pw_global_add_listener(ld->global, &ld->global_listener, &global_events, ld);
|
||||
|
||||
res = pw_global_bind(ld->global, client, PW_PERM_RWX, PW_VERSION_LINK_PROXY, ld->new_id);
|
||||
if (res < 0)
|
||||
goto error_bind;
|
||||
|
||||
if (!ld->linger) {
|
||||
ld->resource = pw_client_find_resource(client, ld->new_id);
|
||||
if (ld->resource == NULL) {
|
||||
res = -ENOENT;
|
||||
goto error_bind;
|
||||
}
|
||||
pw_resource_add_listener(ld->resource, &ld->resource_listener, &resource_events, ld);
|
||||
}
|
||||
return;
|
||||
|
||||
error_bind:
|
||||
pw_resource_errorf(ld->factory_resource, res, "can't bind link: %s", spa_strerror(res));
|
||||
}
|
||||
|
||||
static const struct pw_link_events link_events = {
|
||||
PW_VERSION_LINK_EVENTS,
|
||||
.destroy = link_destroy,
|
||||
.initialized = link_initialized
|
||||
};
|
||||
|
||||
static struct pw_port *get_port(struct pw_node *node, enum spa_direction direction)
|
||||
{
|
||||
struct pw_port *p;
|
||||
|
|
@ -233,29 +267,16 @@ static void *create_object(void *_data,
|
|||
|
||||
ld = pw_link_get_user_data(link);
|
||||
ld->data = d;
|
||||
ld->factory_resource = resource;
|
||||
ld->link = link;
|
||||
ld->new_id = new_id;
|
||||
ld->linger = linger;
|
||||
spa_list_append(&d->link_list, &ld->l);
|
||||
|
||||
pw_link_add_listener(link, &ld->link_listener, &link_events, ld);
|
||||
if ((res = pw_link_register(link, NULL)) < 0)
|
||||
goto error_link_register;
|
||||
|
||||
ld->global = pw_link_get_global(link);
|
||||
pw_global_add_listener(ld->global, &ld->global_listener, &global_events, ld);
|
||||
|
||||
res = pw_global_bind(ld->global, client, PW_PERM_RWX, PW_VERSION_LINK_PROXY, new_id);
|
||||
if (res < 0)
|
||||
goto error_bind;
|
||||
|
||||
if (!linger) {
|
||||
ld->resource = pw_client_find_resource(client, new_id);
|
||||
if (ld->resource == NULL) {
|
||||
res = -ENOENT;
|
||||
goto error_bind;
|
||||
}
|
||||
pw_resource_add_listener(ld->resource, &ld->resource_listener, &resource_events, ld);
|
||||
}
|
||||
|
||||
return link;
|
||||
|
||||
error_properties:
|
||||
|
|
@ -291,9 +312,6 @@ error_link_register:
|
|||
pw_log_error("can't register link: %s", spa_strerror(res));
|
||||
pw_resource_errorf(resource, res, "can't register link: %s", spa_strerror(res));
|
||||
goto error_exit;
|
||||
error_bind:
|
||||
pw_resource_errorf(resource, res, "can't bind link: %s", spa_strerror(res));
|
||||
goto error_exit;
|
||||
error_exit:
|
||||
if (properties)
|
||||
pw_properties_free(properties);
|
||||
|
|
|
|||
|
|
@ -124,25 +124,19 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
data->impl = impl;
|
||||
data->resource = resource;
|
||||
|
||||
pw_log_debug(".");
|
||||
// pw_resource_install_marshal(resource, true);
|
||||
|
||||
/* listen for when the resource goes away */
|
||||
pw_resource_add_listener(resource,
|
||||
&data->resource_listener,
|
||||
&resource_events, data);
|
||||
|
||||
/* resource methods -> implemention */
|
||||
pw_log_debug(".");
|
||||
pw_resource_add_object_listener(resource,
|
||||
&data->object_listener,
|
||||
&metadata_methods, data);
|
||||
/* implementation events -> resource */
|
||||
pw_log_debug(". %p", impl->metadata);
|
||||
pw_metadata_add_listener(impl->metadata,
|
||||
&data->metadata_listener,
|
||||
&metadata_events, data);
|
||||
pw_log_debug(".");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue