diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index 27e8587b8..cc6d72c4c 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -243,10 +243,12 @@ static void client_free(void *data) struct client_data *this = data; struct pw_client *client = this->client; - pw_loop_destroy_source(client->protocol->core->main_loop, this->source); spa_list_remove(&client->protocol_link); - pw_protocol_native_connection_destroy(this->connection); + if (this->source) + pw_loop_destroy_source(client->protocol->core->main_loop, this->source); + if (this->connection) + pw_protocol_native_connection_destroy(this->connection); } static const struct pw_client_events client_events = { @@ -276,44 +278,48 @@ static struct pw_client *client_new(struct server *s, int fd) props = pw_properties_new(PW_CLIENT_PROP_PROTOCOL, "protocol-native", NULL); if (props == NULL) - goto no_props; + goto exit; client = pw_client_new(protocol->core, ucredp, props, sizeof(struct client_data)); if (client == NULL) - goto no_client; + goto exit; this = pw_client_get_user_data(client); + client->protocol = protocol; + spa_list_append(&s->this.client_list, &client->protocol_link); + this->client = client; this->source = pw_loop_add_io(pw_core_get_main_loop(core), fd, SPA_IO_ERR | SPA_IO_HUP, true, connection_data, this); if (this->source == NULL) - goto no_source; + goto cleanup_client; this->connection = pw_protocol_native_connection_new(protocol->core, fd); if (this->connection == NULL) - goto no_connection; - - client->protocol = protocol; - spa_list_append(&s->this.client_list, &client->protocol_link); + goto cleanup_client; pw_client_add_listener(client, &this->client_listener, &client_events, this); - pw_global_bind(pw_core_get_global(core), client, PW_PERM_RWX, PW_VERSION_CORE, 0); + if (pw_global_bind(pw_core_get_global(core), client, + PW_PERM_RWX, PW_VERSION_CORE, 0) < 0) + goto cleanup_client; props = pw_properties_copy(pw_client_get_properties(client)); - pw_client_register(client, client, pw_module_get_global(pd->module), props); + if (pw_client_register(client, client, pw_module_get_global(pd->module), props) < 0) + goto cleanup_client; + + if (pw_global_bind(pw_client_get_global(client), client, + PW_PERM_RWX, PW_VERSION_CLIENT, 1) < 0) + goto cleanup_client; return client; - no_connection: - pw_loop_destroy_source(pw_core_get_main_loop(core), this->source); - no_source: + cleanup_client: pw_client_destroy(client); - no_client: - no_props: + exit: return NULL; } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 077f22de7..dc7060ca8 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -558,6 +558,7 @@ struct pw_remote { struct pw_core_proxy *core_proxy; /**< proxy for the core object */ struct pw_map objects; /**< map of client side proxy objects * indexed with the client id */ + struct pw_client_proxy *client_proxy; /**< proxy for the client object */ struct spa_list proxy_list; /**< list of \ref pw_proxy objects */ struct spa_list stream_list; /**< list of \ref pw_stream objects */ diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 32ef84389..bbc1a74a6 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -351,6 +351,11 @@ static int do_connect(struct pw_remote *remote) if (remote->core_proxy == NULL) goto no_proxy; + remote->client_proxy = (struct pw_client_proxy*)pw_proxy_new(&dummy, + PW_TYPE_INTERFACE_Client, PW_VERSION_CLIENT); + if (remote->client_proxy == NULL) + goto clean_core_proxy; + pw_core_proxy_add_listener(remote->core_proxy, &impl->core_listener, &core_proxy_events, remote); pw_core_proxy_client_update(remote->core_proxy, &remote->properties->dict); @@ -359,6 +364,8 @@ static int do_connect(struct pw_remote *remote) return 0; + clean_core_proxy: + pw_proxy_destroy((struct pw_proxy*)remote->core_proxy); no_proxy: pw_protocol_client_disconnect(remote->conn); pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, "can't connect: no memory"); @@ -370,6 +377,11 @@ struct pw_core_proxy * pw_remote_get_core_proxy(struct pw_remote *remote) return remote->core_proxy; } +struct pw_client_proxy * pw_remote_get_client_proxy(struct pw_remote *remote) +{ + return remote->client_proxy; +} + struct pw_proxy *pw_remote_find_proxy(struct pw_remote *remote, uint32_t id) { return pw_map_lookup(&remote->objects, id); @@ -438,6 +450,7 @@ int pw_remote_disconnect(struct pw_remote *remote) pw_protocol_client_disconnect (remote->conn); remote->core_proxy = NULL; + remote->client_proxy = NULL; pw_remote_update_state(remote, PW_REMOTE_STATE_UNCONNECTED, NULL); diff --git a/src/pipewire/remote.h b/src/pipewire/remote.h index f0ebfb63b..f53458f05 100644 --- a/src/pipewire/remote.h +++ b/src/pipewire/remote.h @@ -193,6 +193,8 @@ int pw_remote_steal_fd(struct pw_remote *remote); /** Get the core proxy, can only be called when connected */ struct pw_core_proxy * pw_remote_get_core_proxy(struct pw_remote *remote); +/** Get the client proxy, can only be called when connected */ +struct pw_client_proxy * pw_remote_get_client_proxy(struct pw_remote *remote); /** Get the proxy with the given id */ struct pw_proxy *pw_remote_find_proxy(struct pw_remote *remote, uint32_t id);