diff --git a/src/modules/module-adapter.c b/src/modules/module-adapter.c index afc0e3c33..780d6d0bc 100644 --- a/src/modules/module-adapter.c +++ b/src/modules/module-adapter.c @@ -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); diff --git a/src/modules/module-link-factory.c b/src/modules/module-link-factory.c index 502e73c22..2c58ce804 100644 --- a/src/modules/module-link-factory.c +++ b/src/modules/module-link-factory.c @@ -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); diff --git a/src/modules/module-metadata/metadata.c b/src/modules/module-metadata/metadata.c index e5e0bc00e..cd77f4792 100644 --- a/src/modules/module-metadata/metadata.c +++ b/src/modules/module-metadata/metadata.c @@ -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; }