diff --git a/src/pipewire/core.c b/src/pipewire/core.c index 48ffaa14a..dcf0def6d 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -105,8 +105,10 @@ static const struct pw_resource_events resource_events = { static int destroy_resource(void *object, void *data) { struct pw_resource *resource = object; - if (resource && resource != resource->client->core_resource) + if (resource && resource != resource->client->core_resource) { + resource->removed = true; pw_resource_destroy(resource); + } return 0; } diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index 3794f702d..9217ce9c3 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -117,6 +117,9 @@ struct pw_core_proxy_methods { /** * Start a conversation with the server. This will send * the core info and server types. + * + * All the existing resources for the client (except the core + * resource) will be destroyed. */ void (*hello) (void *object); /** diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 17e8884bf..42612f1da 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -435,6 +435,8 @@ struct pw_resource { uint32_t type; /**< type of the client interface */ uint32_t version; /**< version of the client interface */ + bool removed; /**< if the resource was removed */ + struct spa_hook implementation; struct spa_hook_list implementation_list; struct spa_hook_list listener_list; diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 173eb4fe9..f63a973a4 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -181,10 +181,12 @@ static void core_event_remove_id(void *data, uint32_t id) struct pw_proxy *proxy; pw_log_debug("remote %p: object remove %u", this, id); - if ((proxy = pw_map_lookup(&this->objects, id)) != NULL) { - pw_proxy_destroy(proxy); - pw_map_remove(&this->objects, id); + if ((proxy = pw_map_lookup(&this->objects, id)) == NULL) { + pw_log_warn("remote %p: asked to remove unknown object id %u", this, id); + return; } + pw_proxy_destroy(proxy); + pw_map_remove(&this->objects, id); } static void diff --git a/src/pipewire/resource.c b/src/pipewire/resource.c index 21959ca31..a3fc53944 100644 --- a/src/pipewire/resource.c +++ b/src/pipewire/resource.c @@ -176,7 +176,7 @@ void pw_resource_destroy(struct pw_resource *resource) pw_map_insert_at(&client->objects, resource->id, NULL); pw_client_events_resource_removed(client, resource); - if (client->core_resource) + if (client->core_resource && !resource->removed) pw_core_resource_remove_id(client->core_resource, resource->id); pw_log_debug("resource %p: free", resource);