diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index 228af7590..af6a4c238 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -557,7 +557,11 @@ on_remote_data(void *data, int fd, uint32_t mask) this, msg->opcode, msg->id); continue; } - if (demarshal[msg->opcode].func(proxy, msg) < 0) { + proxy->refcount++; + res = demarshal[msg->opcode].func(proxy, msg); + pw_proxy_unref(proxy); + + if (res < 0) { pw_log_error (NAME" %p: invalid message received %u for %u", this, msg->opcode, msg->id); continue; diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 27f0b3747..675235ceb 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -654,6 +654,7 @@ struct pw_proxy { struct pw_remote *remote; /**< the owner remote of this proxy */ uint32_t id; /**< client side id */ + int refcount; unsigned int zombie:1; /**< proxy is removed locally and waiting to * be removed from server */ unsigned int removed:1; /**< proxy was removed from server */ @@ -910,6 +911,8 @@ int pw_control_remove_link(struct pw_control_link *link); void pw_control_destroy(struct pw_control *control); +void pw_proxy_unref(struct pw_proxy *proxy); + /** \endcond */ #ifdef __cplusplus diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c index ac581fe94..537a93e27 100644 --- a/src/pipewire/proxy.c +++ b/src/pipewire/proxy.c @@ -70,6 +70,7 @@ struct pw_proxy *pw_proxy_new(struct pw_proxy *factory, this = &impl->this; this->remote = remote; + this->refcount = 1; this->marshal = pw_protocol_get_marshal(remote->conn->protocol, type); if (this->marshal == NULL) { @@ -156,7 +157,6 @@ void pw_proxy_add_object_listener(struct pw_proxy *proxy, SPA_EXPORT void pw_proxy_destroy(struct pw_proxy *proxy) { - struct proxy *impl = SPA_CONTAINER_OF(proxy, struct proxy, this); struct pw_remote *remote = proxy->remote; if (!proxy->zombie) { @@ -175,11 +175,21 @@ void pw_proxy_destroy(struct pw_proxy *proxy) } if (proxy->removed) { pw_map_remove(&remote->objects, proxy->id); - pw_log_debug(NAME" %p: free %u", proxy, proxy->id); - free(impl); + + pw_proxy_unref(proxy); } } +SPA_EXPORT +void pw_proxy_unref(struct pw_proxy *proxy) +{ + if (--proxy->refcount > 0) + return; + + pw_log_debug(NAME" %p: free %u", proxy, proxy->id); + free(proxy); +} + SPA_EXPORT int pw_proxy_sync(struct pw_proxy *proxy, int seq) {