Browse Source

fix up port connection notification design; extend evmon client to test it

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@1047 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
paul 18 years ago
parent
commit
156b955fb4
6 changed files with 110 additions and 57 deletions
  1. +1
    -1
      configure.ac
  2. +10
    -1
      example-clients/evmon.c
  3. +1
    -1
      jack/jack.h
  4. +1
    -1
      jack/types.h
  5. +44
    -2
      jackd/engine.c
  6. +53
    -51
      libjack/client.c

+ 1
- 1
configure.ac View File

@@ -17,7 +17,7 @@ dnl changes are made
dnl ---
JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=107
JACK_MICRO_VERSION=0
JACK_MICRO_VERSION=1

dnl ---
dnl HOWTO: updating the jack protocol version


+ 10
- 1
example-clients/evmon.c View File

@@ -30,6 +30,12 @@ port_callback (jack_port_id_t port, int yn, void* arg)
printf ("Port %d %s\n", port, (yn ? "registered" : "unregistered"));
}

void
connect_callback (jack_port_id_t a, jack_port_id_t b, int yn, void* arg)
{
printf ("Ports %d and %d %s\n", a, b, (yn ? "connected" : "disconnected"));
}

void
client_callback (const char* client, int yn, void* arg)
{
@@ -63,6 +69,10 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot set port registration callback\n");
return 1;
}
if (jack_set_port_connect_callback (client, connect_callback, NULL)) {
fprintf (stderr, "cannot set port connect callback\n");
return 1;
}
if (jack_set_client_registration_callback (client, client_callback, NULL)) {
fprintf (stderr, "cannot set client registration callback\n");
return 1;
@@ -71,7 +81,6 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot set graph order registration callback\n");
return 1;
}

if (jack_activate (client)) {
fprintf (stderr, "cannot activate client");
return 1;


+ 1
- 1
jack/jack.h View File

@@ -311,7 +311,7 @@ int jack_set_port_registration_callback (jack_client_t *,

/**
* Tell the JACK server to call @a connect_callback whenever a
* port is registered or unregistered, passing @a arg as a parameter.
* port is connected or disconnected, passing @a arg as a parameter.
*
* @return 0 on success, otherwise a non-zero error code
*/


+ 1
- 1
jack/types.h View File

@@ -182,7 +182,7 @@ typedef void (*JackClientRegistrationCallback)(const char* name, int register, v
* zero if ports were disconnected
* @param arg pointer to a client supplied data
*/
typedef void (*JackPortConnectCallback)(jack_port_t* a, jack_port_t* b, int connect, void* arg);
typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int connect, void* arg);

/**
* Prototype for the client supplied function that is called


+ 44
- 2
jackd/engine.c View File

@@ -108,6 +108,10 @@ static int jack_deliver_event (jack_engine_t *, jack_client_internal_t *,
jack_event_t *);
static void jack_deliver_event_to_all (jack_engine_t *engine,
jack_event_t *event);
static void jack_notify_all_port_interested_clients (jack_engine_t *engine,
jack_port_id_t a,
jack_port_id_t b,
int connect);
static void jack_engine_post_process (jack_engine_t *);
static int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver);
static int jack_run_cycle (jack_engine_t *engine, jack_nframes_t nframes,
@@ -2276,6 +2280,34 @@ jack_deliver_event_to_all (jack_engine_t *engine, jack_event_t *event)
jack_unlock_graph (engine);
}

static void
jack_notify_all_port_interested_clients (jack_engine_t *engine, jack_port_id_t a, jack_port_id_t b, int connected)
{
JSList *node;
jack_event_t event;

event.type = (connected ? PortConnected : PortDisconnected);
event.x.self_id = a;
event.y.other_id = b;
/* GRAPH MUST BE LOCKED : see callers of jack_send_connection_notification()
*/

for (node = engine->clients; node; node = jack_slist_next (node)) {
jack_client_internal_t* client;

client = (jack_client_internal_t*) node->data;

if (client->control->port_connect != NULL) {
/* one of the ports belong to this client or it has a port connect callback */
jack_deliver_event (engine, client, &event);
}
}
}

static int
jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client,
jack_event_t *event)
@@ -3128,10 +3160,16 @@ jack_port_do_connect (jack_engine_t *engine,
jack_send_connection_notification (engine,
srcport->shared->client_id,
src_id, dst_id, TRUE);

jack_send_connection_notification (engine,
dstport->shared->client_id,
dst_id, src_id, TRUE);
/* send a port connection notification just once to everyone who cares */

jack_notify_all_port_interested_clients (engine, src_id, dst_id, 1);

jack_sort_graph (engine);
}

@@ -3193,6 +3231,10 @@ jack_port_disconnect_internal (jack_engine_t *engine,
engine, dstport->shared->client_id, dst_id,
src_id, FALSE);

/* send a port connection notification just once to everyone who cares */
jack_notify_all_port_interested_clients (engine, src_id, dst_id, 0);

if (connect->dir) {
jack_client_internal_t *src;
@@ -3812,8 +3854,8 @@ jack_send_connection_notification (jack_engine_t *engine,

{
jack_client_internal_t *client;
jack_event_t event;
jack_event_t event;
if ((client = jack_client_internal_by_id (engine, client_id)) == NULL) {
jack_error ("no such client %" PRIu32
" during connection notification", client_id);


+ 53
- 51
libjack/client.c View File

@@ -426,62 +426,64 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)
JSList *node;
int need_free = FALSE;

switch (event->type) {
case PortConnected:
other = jack_port_new (client, event->y.other_id,
client->engine);
/* jack_port_by_id_int() always returns an internal
* port that does not need to be deallocated */
control_port = jack_port_by_id_int (client, event->x.self_id,
&need_free);
pthread_mutex_lock (&control_port->connection_lock);
control_port->connections =
jack_slist_prepend (control_port->connections,
(void *) other);
pthread_mutex_unlock (&control_port->connection_lock);
if (client->control->port_connect) {
client->control->port_connect (control_port, other, 1, client->control->port_connect_arg);
}

break;
if (client->engine->ports[event->x.self_id].client_id == client->control->id ||
client->engine->ports[event->y.other_id].client_id == client->control->id) {

case PortDisconnected:
/* jack_port_by_id_int() always returns an internal
* port that does not need to be deallocated */
control_port = jack_port_by_id_int (client, event->x.self_id,
&need_free);
pthread_mutex_lock (&control_port->connection_lock);
/* its one of ours */

for (node = control_port->connections; node;
node = jack_slist_next (node)) {

other = (jack_port_t *) node->data;

if (other->shared->id == event->y.other_id) {
control_port->connections =
jack_slist_remove_link (
control_port->connections,
node);
break;
}
}

pthread_mutex_unlock (&control_port->connection_lock);

if (node) {
if (client->control->port_connect) {
client->control->port_connect (control_port, other, 0, client->control->port_connect_arg);
switch (event->type) {
case PortConnected:
other = jack_port_new (client, event->y.other_id,
client->engine);
/* jack_port_by_id_int() always returns an internal
* port that does not need to be deallocated
*/
control_port = jack_port_by_id_int (client, event->x.self_id,
&need_free);
pthread_mutex_lock (&control_port->connection_lock);
control_port->connections =
jack_slist_prepend (control_port->connections,
(void *) other);
pthread_mutex_unlock (&control_port->connection_lock);
break;
case PortDisconnected:
/* jack_port_by_id_int() always returns an internal
* port that does not need to be deallocated
*/
control_port = jack_port_by_id_int (client, event->x.self_id,
&need_free);
pthread_mutex_lock (&control_port->connection_lock);
for (node = control_port->connections; node;
node = jack_slist_next (node)) {
other = (jack_port_t *) node->data;

if (other->shared->id == event->y.other_id) {
control_port->connections =
jack_slist_remove_link (
control_port->connections,
node);
jack_slist_free_1 (node);
free (other);
break;
}
}
jack_slist_free_1 (node);
free (other);
pthread_mutex_unlock (&control_port->connection_lock);
break;
default:
/* impossible */
break;
}
}

break;

default:
/* impossible */
break;
if (client->control->port_connect) {
client->control->port_connect (event->x.self_id, event->y.other_id,
(event->type == PortConnected ? 1 : 0),
client->control->port_connect_arg);
}

return 0;


Loading…
Cancel
Save