diff --git a/pinos/client/context.c b/pinos/client/context.c index e7f2e01a3..965bff37e 100644 --- a/pinos/client/context.c +++ b/pinos/client/context.c @@ -121,7 +121,6 @@ core_dispatch_func (void *object, proxy = pinos_map_lookup (&this->objects, m->id); if (proxy) { pinos_log_debug ("context %p: object remove %u", this, m->id); - pinos_map_remove (&this->objects, m->id); pinos_proxy_destroy (proxy); } break; diff --git a/pinos/client/map.h b/pinos/client/map.h index b827a19f7..976709b9c 100644 --- a/pinos/client/map.h +++ b/pinos/client/map.h @@ -113,7 +113,7 @@ pinos_map_for_each (PinosMap *map, PinosMapItem *item; pinos_array_for_each (item, &map->items) { - if (!pinos_map_item_is_free (item)) + if (item->data && !pinos_map_item_is_free (item)) func (item->data, data); } } diff --git a/pinos/server/client.c b/pinos/server/client.c index 3f290c602..5ec7fa622 100644 --- a/pinos/server/client.c +++ b/pinos/server/client.c @@ -46,6 +46,13 @@ client_dispatch_func (void *object, return SPA_RESULT_OK; } +static void +client_unbind_func (void *data) +{ + PinosResource *resource = data; + spa_list_remove (&resource->link); +} + static void client_bind_func (PinosGlobal *global, PinosClient *client, @@ -61,13 +68,15 @@ client_bind_func (PinosGlobal *global, id, global->core->uri.client, global->object, - NULL); + client_unbind_func); resource->dispatch_func = client_dispatch_func; resource->dispatch_data = global; pinos_log_debug ("client %p: bound to %d", global->object, resource->id); + spa_list_insert (this->resource_list.prev, &resource->link); + m.info = &info; info.id = resource->id; info.change_mask = ~0; @@ -102,6 +111,8 @@ pinos_client_new (PinosCore *core, this->core = core; this->properties = properties; + spa_list_init (&this->resource_list); + pinos_map_init (&this->objects, 64); pinos_signal_init (&this->destroy_signal); @@ -149,6 +160,8 @@ destroy_resource (void *object, void pinos_client_destroy (PinosClient * client) { + PinosResource *resource, *tmp; + pinos_log_debug ("client %p: destroy", client); pinos_signal_emit (&client->destroy_signal, client); @@ -157,6 +170,9 @@ pinos_client_destroy (PinosClient * client) pinos_global_destroy (client->global); spa_list_remove (&client->link); + spa_list_for_each_safe (resource, tmp, &client->resource_list, link) + pinos_resource_destroy (resource); + pinos_main_loop_defer (client->core->main_loop, client, SPA_RESULT_WAIT_SYNC, diff --git a/pinos/server/client.h b/pinos/server/client.h index 07257d79a..7131a1724 100644 --- a/pinos/server/client.h +++ b/pinos/server/client.h @@ -45,6 +45,8 @@ struct _PinosClient { PinosMap objects; + SpaList resource_list; + PinosSendFunc send_func; void *send_data; diff --git a/pinos/server/core.c b/pinos/server/core.c index 71a820a1c..e05dee76a 100644 --- a/pinos/server/core.c +++ b/pinos/server/core.c @@ -326,7 +326,7 @@ pinos_global_destroy (PinosGlobal *global) PinosResource *registry; PinosMessageNotifyGlobalRemove ng; - pinos_log_debug ("global %p: destroy", global); + pinos_log_debug ("global %p: destroy %u", global, global->id); pinos_signal_emit (&global->destroy_signal, global); pinos_map_remove (&core->objects, global->id); diff --git a/pinos/server/link.c b/pinos/server/link.c index 35d62948a..2f23f56fe 100644 --- a/pinos/server/link.c +++ b/pinos/server/link.c @@ -892,6 +892,7 @@ pinos_link_destroy (PinosLink * this) { SpaResult res = SPA_RESULT_OK; PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this); + PinosResource *resource, *tmp; pinos_log_debug ("link %p: destroy", impl); pinos_signal_emit (&this->destroy_signal, this); @@ -899,6 +900,9 @@ pinos_link_destroy (PinosLink * this) pinos_global_destroy (this->global); spa_list_remove (&this->link); + spa_list_for_each_safe (resource, tmp, &this->resource_list, link) + pinos_resource_destroy (resource); + if (this->input) { pinos_signal_remove (&impl->input_port_destroy); pinos_signal_remove (&impl->input_async_complete); diff --git a/pinos/server/node.c b/pinos/server/node.c index 624277b8f..33bf19c32 100644 --- a/pinos/server/node.c +++ b/pinos/server/node.c @@ -630,6 +630,7 @@ pinos_node_destroy (PinosNode * this) { SpaResult res; PinosNodeImpl *impl = SPA_CONTAINER_OF (this, PinosNodeImpl, this); + PinosResource *resource, *tmp; pinos_log_debug ("node %p: destroy", impl); pinos_signal_emit (&this->destroy_signal, this); @@ -637,6 +638,9 @@ pinos_node_destroy (PinosNode * this) spa_list_remove (&this->link); pinos_global_destroy (this->global); + spa_list_for_each_safe (resource, tmp, &this->resource_list, link) + pinos_resource_destroy (resource); + res = pinos_loop_invoke (this->data_loop->loop, do_node_remove, impl->seq++, diff --git a/pinos/server/resource.c b/pinos/server/resource.c index c5963e402..b15ff1ba0 100644 --- a/pinos/server/resource.c +++ b/pinos/server/resource.c @@ -71,6 +71,15 @@ pinos_resource_destroy (PinosResource *resource) if (resource->destroy) resource->destroy (resource); + if (resource->client->core_resource) { + PinosMessageRemoveId m; + m.id = resource->id; + pinos_resource_send_message (resource->client->core_resource, + PINOS_MESSAGE_REMOVE_ID, + &m, + true); + } + pinos_main_loop_defer (resource->core->main_loop, resource, SPA_RESULT_WAIT_SYNC,