diff --git a/src/modules/module-jack.c b/src/modules/module-jack.c index bec2b0213..b6612be5b 100644 --- a/src/modules/module-jack.c +++ b/src/modules/module-jack.c @@ -81,6 +81,7 @@ struct impl { struct spa_list socket_list; struct spa_list client_list; + struct spa_list link_list; struct spa_loop_control_hooks hooks; @@ -120,6 +121,7 @@ struct link { struct pw_jack_port *out_port; struct pw_jack_port *in_port; struct spa_hook link_listener; + struct spa_list link_link; }; static bool init_socket_name(struct sockaddr_un *addr, const char *name, bool promiscuous, int which) @@ -609,6 +611,8 @@ static void link_destroy(void *data) pw_log_debug("module-jack %p: link %p destroy", impl, ld->link); + spa_list_remove(&ld->link_link); + conn = jack_graph_manager_next_start(mgr); if (jack_connection_manager_is_connected(conn, src_id, dst_id)) { if (jack_connection_manager_disconnect_ports(conn, src_id, dst_id)) { @@ -731,6 +735,7 @@ handle_connect_name_ports(struct client *client) ld->link = link; ld->out_port = out_port; ld->in_port = in_port; + spa_list_append(&impl->link_list, &ld->link_link); pw_link_add_listener(link, &ld->link_listener, &link_events, ld); pw_link_activate(link); @@ -745,6 +750,34 @@ handle_connect_name_ports(struct client *client) return 0; } +static int +handle_disconnect_name_ports(struct client *client) +{ + struct link *link, *t; + struct impl *impl = client->impl; + int result = -1; + int ref_num; + char src[REAL_JACK_PORT_NAME_SIZE+1]; + char dst[REAL_JACK_PORT_NAME_SIZE+1]; + + CheckSize(kDisconnectNamePorts_size); + CheckRead(&ref_num, sizeof(int)); + CheckRead(src, sizeof(src)); + CheckRead(dst, sizeof(dst)); + + spa_list_for_each_safe(link, t, &impl->link_list, link_link) { + if ((strcmp(link->out_port->jack_port->name, src) == 0) && + (strcmp(link->in_port->jack_port->name, dst) == 0)) { + pw_link_destroy(link->link); + result = 0; + break; + } + } + + CheckWrite(&result, sizeof(int)); + return 0; +} + static int handle_get_UUID_by_client(struct client *client) { @@ -814,6 +847,7 @@ process_messages(struct client *client) res = handle_connect_name_ports(client); break; case jack_request_DisconnectNamePorts: + res = handle_disconnect_name_ports(client); break; case jack_request_GetInternalClientName: case jack_request_InternalClientHandle: @@ -1318,6 +1352,7 @@ static struct impl *module_init(struct pw_module *module, struct pw_properties * spa_list_init(&impl->socket_list); spa_list_init(&impl->client_list); + spa_list_init(&impl->link_list); spa_list_init(&impl->rt.nodes); str = NULL; diff --git a/src/modules/module-jack/defs.h b/src/modules/module-jack/defs.h index ac3812513..580ec2471 100644 --- a/src/modules/module-jack/defs.h +++ b/src/modules/module-jack/defs.h @@ -132,6 +132,7 @@ enum jack_notification_type { #define kClientOpen_size (JACK_CLIENT_NAME_SIZE+1 + 2 * sizeof(int)) #define kClientClose_size (sizeof(int)) #define kConnectNamePorts_size (sizeof(int) + REAL_JACK_PORT_NAME_SIZE+1 + REAL_JACK_PORT_NAME_SIZE+1) +#define kDisconnectNamePorts_size (sizeof(int) + REAL_JACK_PORT_NAME_SIZE+1 + REAL_JACK_PORT_NAME_SIZE+1) #define kGetUUIDByClient_size (JACK_CLIENT_NAME_SIZE+1) #define CheckRead(var,size) if(read(client->fd,var,size)!=size) {pw_log_error("read error"); return -1; } diff --git a/src/pipewire/link.c b/src/pipewire/link.c index c3ebc6ba1..9bba9d1a6 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -1150,6 +1150,8 @@ void pw_link_destroy(struct pw_link *link) spa_hook_list_call(&link->output->listener_list, struct pw_port_events, link_removed, link); link->output = NULL; + spa_hook_list_call(&link->listener_list, struct pw_link_events, free); + pw_work_queue_destroy(impl->work); if (link->info.format) diff --git a/src/pipewire/link.h b/src/pipewire/link.h index 1eacd57c6..5b4edd901 100644 --- a/src/pipewire/link.h +++ b/src/pipewire/link.h @@ -54,6 +54,8 @@ struct pw_link_events { void (*destroy) (void *data); + void (*free) (void *data); + void (*info_changed) (void *data, const struct pw_link_info *info); void (*state_changed) (void *data, enum pw_link_state old,