From 325280cbdab53283e8f26f9a58999127ba1003e1 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 3 Jun 2020 16:54:46 +0200 Subject: [PATCH] core: run extra step to warn/destroy leaked proxies Don't set the core to NULL in _remove so that the proxies will be removed from the map when they are destroyed. Then make another run over the map to warn about the proxies that were not destroyed. --- src/pipewire/core.c | 26 +++++++++++++++++++++----- src/pipewire/proxy.c | 12 ++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/pipewire/core.c b/src/pipewire/core.c index 7e502f5f2..695a88017 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -173,14 +173,27 @@ static int remove_proxy(void *object, void *data) if (object == NULL) return 0; - if (object != core) { - p->core = NULL; + if (object != core) pw_proxy_remove(p); - } return 0; } +static int destroy_proxy(void *object, void *data) +{ + struct pw_core *core = data; + struct pw_proxy *p = object; + + if (object == NULL) + return 0; + + if (object != core) { + pw_log_warn(NAME" %p: destroy leaked proxy %d", core, p->id); + pw_proxy_destroy(p); + } + return 0; +} + static void proxy_core_removed(void *data) { struct pw_core *core = data; @@ -201,7 +214,6 @@ static void proxy_core_removed(void *data) pw_filter_disconnect(filter); pw_map_for_each(&core->objects, remove_proxy, core); - pw_map_reset(&core->objects); } static void proxy_core_destroy(void *data) @@ -222,9 +234,13 @@ static void proxy_core_destroy(void *data) spa_list_consume(filter, &core->filter_list, link) pw_filter_destroy(filter); - pw_protocol_client_disconnect(core->conn); pw_proxy_destroy((struct pw_proxy*)core->client); + pw_map_for_each(&core->objects, destroy_proxy, core); + pw_map_reset(&core->objects); + + pw_protocol_client_disconnect(core->conn); + pw_mempool_destroy(core->pool); pw_protocol_client_destroy(core->conn); diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c index a5fb959df..f387b2fcf 100644 --- a/src/pipewire/proxy.c +++ b/src/pipewire/proxy.c @@ -213,8 +213,7 @@ void pw_proxy_add_object_listener(struct pw_proxy *proxy, static inline void remove_from_map(struct pw_proxy *proxy) { if (proxy->in_map) { - if (proxy->core) - pw_map_remove(&proxy->core->objects, proxy->id); + pw_map_remove(&proxy->core->objects, proxy->id); proxy->in_map = false; } } @@ -239,7 +238,7 @@ void pw_proxy_destroy(struct pw_proxy *proxy) if (!proxy->removed) { /* if the server did not remove this proxy, schedule a * destroy if we can */ - if (proxy->core) { + if (!proxy->core->removed) { pw_core_destroy(proxy->core, proxy); proxy->refcount++; } else { @@ -303,7 +302,7 @@ int pw_proxy_sync(struct pw_proxy *proxy, int seq) int res = -EIO; struct pw_core *core = proxy->core; - if (core != NULL) { + if (!core->removed) { res = pw_core_sync(core, proxy->id, seq); pw_log_debug(NAME" %p: %u seq:%d sync %u", proxy, proxy->id, seq, res); } @@ -318,7 +317,7 @@ int pw_proxy_errorf(struct pw_proxy *proxy, int res, const char *error, ...) struct pw_core *core = proxy->core; va_start(ap, error); - if (core != NULL) + if (!core->removed) r = pw_core_errorv(core, proxy->id, core->recv_seq, res, error, ap); va_end(ap); @@ -330,7 +329,8 @@ int pw_proxy_error(struct pw_proxy *proxy, int res, const char *error) { int r = -EIO; struct pw_core *core = proxy->core; - if (core != NULL) + + if (!core->removed) r = pw_core_error(core, proxy->id, core->recv_seq, res, error); return r;