diff --git a/client.c b/client.c index 9c5932e..cc2873d 100644 --- a/client.c +++ b/client.c @@ -216,12 +216,16 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event) case PortConnected: other = jack_port_new (client, event->y.other_id, client->engine); control_port = jack_port_by_id (client, event->x.self_id); + pthread_mutex_lock (&control_port->connection_lock); control_port->connections = g_slist_prepend (control_port->connections, other); + pthread_mutex_unlock (&control_port->connection_lock); break; case PortDisconnected: control_port = jack_port_by_id (client, event->x.self_id); + pthread_mutex_lock (&control_port->connection_lock); + for (node = control_port->connections; node; node = g_slist_next (node)) { other = (jack_port_t *) node->data; @@ -233,6 +237,8 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event) break; } } + + pthread_mutex_unlock (&control_port->connection_lock); break; default: @@ -922,6 +928,7 @@ jack_port_new (jack_client_t *client, jack_port_id_t port_id, jack_control_t *co port->client_segment_base = 0; port->shared = shared; + pthread_mutex_init (&port->connection_lock, NULL); port->connections = 0; port->tied = NULL; @@ -1070,10 +1077,15 @@ jack_port_disconnect (jack_client_t *client, jack_port_t *port) { jack_request_t req; + pthread_mutex_lock (&port->connection_lock); + if (port->connections == NULL) { + pthread_mutex_unlock (&port->connection_lock); return 0; } + pthread_mutex_unlock (&port->connection_lock); + req.type = DisconnectPort; req.x.port_info.port_id = port->shared->id; @@ -1182,6 +1194,12 @@ jack_port_get_buffer (jack_port_t *port, nframes_t nframes) /* Input port. */ + /* since this can only be called from the process() callback, + and since no connections can be made/broken during this + phase (enforced by the jack server), there is no need + to take the connection lock here + */ + if ((node = port->connections) == NULL) { /* no connections; return a zero-filled buffer */ @@ -1538,6 +1556,12 @@ jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes) the existence of more than 1 connection to this input port. */ + /* no need to take connection lock, since this is called + from the process() callback, and the jack server + ensures that no changes to connections happen + during this time. + */ + node = port->connections; input = (jack_port_t *) node->data; buffer = jack_port_buffer (port); @@ -1557,3 +1581,30 @@ jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes) } } } + +int +jack_port_connected (const jack_port_t *port) +{ + return port->connections != NULL; +} + +int +jack_port_connected_to (const jack_port_t *port, const char *portname) +{ + GSList *node; + int ret = FALSE; + + pthread_mutex_lock (&((jack_port_t *) port)->connection_lock); + + for (node = port->connections; node; node = g_slist_next (node)) { + jack_port_t *other_port = (jack_port_t *) node->data; + + if (strcmp (other_port->shared->name, portname) == 0) { + ret = TRUE; + break; + } + } + + pthread_mutex_unlock (&((jack_port_t *) port)->connection_lock); + return ret; +} diff --git a/configure.in b/configure.in index 778b1b8..aeb6b04 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_INIT(client.c) AC_CONFIG_AUX_DIR(.) JACK_MAJOR_VERSION=0 -JACK_MINOR_VERSION=7 +JACK_MINOR_VERSION=8 JACK_MICRO_VERSION=0 BETA= diff --git a/jack/jack.h b/jack/jack.h index 1a95296..6c6facd 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -126,6 +126,7 @@ const char * jack_port_short_name (const jack_port_t *port); int jack_port_flags (const jack_port_t *port); const char * jack_port_type (const jack_port_t *port); int jack_port_connected (const jack_port_t *port); +int jack_port_connected_to (const jack_port_t *port, const char *portname); int jack_port_equal (const jack_port_t *a, const jack_port_t *b); int jack_port_set_name (jack_port_t *port, const char *name); diff --git a/jack/port.h b/jack/port.h index 0537e2b..19b5863 100644 --- a/jack/port.h +++ b/jack/port.h @@ -77,6 +77,7 @@ typedef struct _jack_port_shared { struct _jack_port { char *client_segment_base; struct _jack_port_shared *shared; + pthread_mutex_t connection_lock; GSList *connections; struct _jack_port *tied; };