From 1934df7307f8aea603bebadc4b432717d3706d8f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 26 Nov 2020 09:28:22 +0100 Subject: [PATCH] pulse-server: implement OBJECT_LINGER Use OBJECT_LINGER in module-load to make sure the module stays loaded after the client disconnects. Implement linger in adapter and node-factory --- src/modules/module-adapter.c | 8 +++++++- src/modules/module-protocol-pulse/module.c | 1 + src/modules/spa/module-node-factory.c | 9 +++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/modules/module-adapter.c b/src/modules/module-adapter.c index e59e9a502..edf6dce99 100644 --- a/src/modules/module-adapter.c +++ b/src/modules/module-adapter.c @@ -69,6 +69,7 @@ struct node_data { struct pw_resource *resource; struct spa_hook resource_listener; uint32_t new_id; + unsigned int linger; }; static void resource_destroy(void *data) @@ -77,7 +78,7 @@ static void resource_destroy(void *data) pw_log_debug(NAME" %p: destroy %p", nd, nd->adapter); spa_hook_remove(&nd->resource_listener); - if (nd->adapter) + if (nd->adapter && !nd->linger) pw_impl_node_destroy(nd->adapter); } @@ -156,6 +157,7 @@ static void *create_object(void *_data, const char *str, *factory_name; int res; struct node_data *nd; + bool linger; if (properties == NULL) goto error_properties; @@ -178,6 +180,9 @@ static void *create_object(void *_data, pw_properties_setf(properties, "audio.adapt.follower", "pointer:%p", follower); } + str = pw_properties_get(properties, PW_KEY_OBJECT_LINGER); + linger = str ? pw_properties_parse_bool(str) : false; + if (follower == NULL) { factory_name = pw_properties_get(properties, SPA_KEY_FACTORY_NAME); if (factory_name == NULL) @@ -211,6 +216,7 @@ static void *create_object(void *_data, nd->follower = follower; nd->resource = resource; nd->new_id = new_id; + nd->linger = linger; spa_list_append(&d->node_list, &nd->link); pw_impl_node_add_listener(adapter, &nd->adapter_listener, &node_events, nd); diff --git a/src/modules/module-protocol-pulse/module.c b/src/modules/module-protocol-pulse/module.c index bf592b1db..091f26245 100644 --- a/src/modules/module-protocol-pulse/module.c +++ b/src/modules/module-protocol-pulse/module.c @@ -176,6 +176,7 @@ static int load_module(struct client *client, const char *name, const char *argu pw_properties_set(props, "device.description", NULL); } pw_properties_set(props, "factory.name", "support.null-audio-sink"); + pw_properties_set(props, PW_KEY_OBJECT_LINGER, "1"); module = calloc(1, sizeof(struct module)); module->client = client; diff --git a/src/modules/spa/module-node-factory.c b/src/modules/spa/module-node-factory.c index 1ee3b3021..ce85dc627 100644 --- a/src/modules/spa/module-node-factory.c +++ b/src/modules/spa/module-node-factory.c @@ -63,6 +63,7 @@ struct node_data { struct pw_impl_node *node; struct spa_hook node_listener; struct spa_hook resource_listener; + unsigned int linger:1; }; static void resource_destroy(void *data) @@ -70,7 +71,7 @@ static void resource_destroy(void *data) struct node_data *nd = data; pw_log_debug("node %p", nd); spa_hook_remove(&nd->resource_listener); - if (nd->node) + if (nd->node && !nd->linger) pw_impl_node_destroy(nd->node); } @@ -103,10 +104,11 @@ static void *create_object(void *_data, struct factory_data *data = _data; struct pw_context *context = data->context; struct pw_impl_node *node; - const char *factory_name; + const char *factory_name, *str; struct node_data *nd; int res; struct pw_impl_client *client; + bool linger; if (properties == NULL) goto error_properties; @@ -124,6 +126,8 @@ static void *create_object(void *_data, pw_properties_setf(properties, PW_KEY_CLIENT_ID, "%d", pw_global_get_id(pw_impl_client_get_global(client))); } + str = pw_properties_get(properties, PW_KEY_OBJECT_LINGER); + linger = str ? pw_properties_parse_bool(str) : false; node = pw_spa_node_load(context, factory_name, @@ -136,6 +140,7 @@ static void *create_object(void *_data, nd = pw_spa_node_get_user_data(node); nd->data = data; nd->node = node; + nd->linger = linger; spa_list_append(&data->node_list, &nd->link); pw_impl_node_add_listener(node, &nd->node_listener, &node_events, nd);