git-svn-id: svn+ssh://jackaudio.org/trunk/jack@589 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
@@ -14,8 +14,8 @@ dnl micro version = incremented when implementation-only | |||
dnl changes are made | |||
dnl --- | |||
JACK_MAJOR_VERSION=0 | |||
JACK_MINOR_VERSION=91 | |||
JACK_MICRO_VERSION=4 | |||
JACK_MINOR_VERSION=92 | |||
JACK_MICRO_VERSION=0 | |||
dnl --- | |||
dnl HOWTO: updating the jack protocal version | |||
@@ -25,7 +25,7 @@ dnl made to the way libjack communicates with jackd | |||
dnl that would break applications linked with an older | |||
dnl version of libjack. | |||
dnl --- | |||
JACK_PROTOCOL_VERSION=11 | |||
JACK_PROTOCOL_VERSION=12 | |||
dnl --- | |||
dnl HOWTO: updating the libjack interface version | |||
@@ -126,6 +126,20 @@ void signal_handler(int sig) | |||
/* Command functions: see commands[] table following. */ | |||
void com_activate(char *arg) | |||
{ | |||
if (jack_activate(client)) { | |||
fprintf(stderr, "cannot activate client"); | |||
} | |||
} | |||
void com_deactivate(char *arg) | |||
{ | |||
if (jack_deactivate(client)) { | |||
fprintf(stderr, "cannot deactivate client"); | |||
} | |||
} | |||
void com_exit(char *arg) | |||
{ | |||
done = 1; | |||
@@ -203,7 +217,9 @@ typedef struct { | |||
/* command table must be in alphabetical order */ | |||
command_t commands[] = { | |||
{"activate", com_activate, "Call jack_activate()"}, | |||
{"exit", com_exit, "Exit transport program"}, | |||
{"deactivate", com_deactivate, "Call jack_deactivate()"}, | |||
{"help", com_help, "Display help text [<command>]"}, | |||
{"locate", com_locate, "Locate to frame <position>"}, | |||
{"master", com_master, "Become timebase master " | |||
@@ -96,7 +96,7 @@ typedef struct { | |||
int8_t new_pos; /* new position this cycle */ | |||
int8_t pending_pos; /* new position request pending */ | |||
jack_nframes_t pending_frame; /* pending frame number */ | |||
uint32_t sync_clients; /* number of is_slowsync clients */ | |||
uint32_t sync_clients; /* number of active slowsync clients */ | |||
uint32_t sync_remain; /* number of them with sync_poll */ | |||
jack_time_t sync_timeout; | |||
jack_time_t sync_time_left; | |||
@@ -170,6 +170,7 @@ typedef volatile struct { | |||
volatile int8_t dead : 1; /* r/w: engine */ | |||
volatile int8_t timed_out : 1; /* r/w: engine */ | |||
volatile int8_t is_timebase : 1; /* w: engine, r: engine and client */ | |||
volatile int8_t timebase_new : 1; /* w: engine and client, r: engine */ | |||
volatile int8_t is_slowsync : 1; /* w: engine, r: engine and client */ | |||
volatile int8_t sync_poll : 1; /* w: engine and client, r: engine */ | |||
volatile int8_t sync_new : 1; /* w: engine and client, r: engine */ | |||
@@ -1447,12 +1447,13 @@ jack_client_activate (jack_engine_t *engine, jack_client_id_t id) | |||
client = (jack_client_internal_t *) node->data; | |||
client->control->active = TRUE; | |||
/* we call this to make sure the | |||
FIFO is built+ready by the time | |||
the client needs it. we don't | |||
care about the return value at | |||
this point. | |||
*/ | |||
jack_transport_activate(engine, client); | |||
/* we call this to make sure the FIFO is | |||
* built+ready by the time the client needs | |||
* it. we don't care about the return value at | |||
* this point. | |||
*/ | |||
jack_get_fifo_fd (engine, | |||
++engine->external_client_cnt); | |||
@@ -1476,6 +1477,8 @@ jack_client_do_deactivate (jack_engine_t *engine, | |||
* cleared all connections held by client. */ | |||
client->control->active = FALSE; | |||
jack_transport_client_exit (engine, client); | |||
if (!jack_client_is_internal (client) && | |||
engine->external_client_cnt > 0) { | |||
engine->external_client_cnt--; | |||
@@ -1527,16 +1530,13 @@ jack_client_deactivate (jack_engine_t *engine, jack_client_id_t id) | |||
JSList *portnode; | |||
jack_port_internal_t *port; | |||
jack_transport_client_exit (engine, client); | |||
for (portnode = client->ports; portnode; | |||
portnode = jack_slist_next (portnode)) { | |||
port = (jack_port_internal_t *) portnode->data; | |||
jack_port_clear_connections (engine, port); | |||
} | |||
ret = jack_client_do_deactivate (engine, node->data, | |||
TRUE); | |||
ret = jack_client_do_deactivate (engine, client, TRUE); | |||
break; | |||
} | |||
} | |||
@@ -68,8 +68,6 @@ jack_sync_poll_exit (jack_engine_t *engine, jack_client_internal_t *client) | |||
VERBOSE (engine, "sync poll interrupted for client %" | |||
PRIu32 "\n", client->control->id); | |||
} | |||
client->control->is_slowsync = 0; | |||
engine->control->sync_clients--; | |||
} | |||
/* stop polling all the slow-sync clients | |||
@@ -85,6 +83,7 @@ jack_sync_poll_stop (jack_engine_t *engine) | |||
jack_client_internal_t *client = | |||
(jack_client_internal_t *) node->data; | |||
if (client->control->is_slowsync && | |||
client->control->active && | |||
client->control->sync_poll) { | |||
client->control->sync_poll = 0; | |||
poll_count++; | |||
@@ -114,7 +113,8 @@ jack_sync_poll_start (jack_engine_t *engine) | |||
for (node = engine->clients; node; node = jack_slist_next (node)) { | |||
jack_client_internal_t *client = | |||
(jack_client_internal_t *) node->data; | |||
if (client->control->is_slowsync) { | |||
if (client->control->is_slowsync && | |||
client->control->active) { | |||
client->control->sync_poll = 1; | |||
sync_count++; | |||
} | |||
@@ -122,7 +122,7 @@ jack_sync_poll_start (jack_engine_t *engine) | |||
//JOQ: check invariant for debugging... | |||
assert (sync_count == engine->control->sync_clients); | |||
engine->control->sync_remain = engine->control->sync_clients; | |||
engine->control->sync_remain = sync_count; | |||
engine->control->sync_time_left = engine->control->sync_timeout; | |||
VERBOSE (engine, "transport Starting, sync poll of %" PRIu32 | |||
" clients for %8.6f secs\n", engine->control->sync_remain, | |||
@@ -177,6 +177,7 @@ jack_timebase_reset (jack_engine_t *engine, jack_client_id_t client_id) | |||
client = jack_client_internal_by_id (engine, client_id); | |||
if (client && (client == engine->timebase_client)) { | |||
client->control->is_timebase = 0; | |||
client->control->timebase_new = 0; | |||
engine->timebase_client = NULL; | |||
ectl->pending_time.valid = 0; | |||
VERBOSE (engine, "%s resigned as timebase master\n", | |||
@@ -223,10 +224,14 @@ jack_timebase_set (jack_engine_t *engine, | |||
} else { | |||
if (engine->timebase_client) | |||
if (engine->timebase_client) { | |||
engine->timebase_client->control->is_timebase = 0; | |||
engine->timebase_client->control->timebase_new = 0; | |||
} | |||
engine->timebase_client = client; | |||
client->control->is_timebase = 1; | |||
if (client->control->active) | |||
client->control->timebase_new = 1; | |||
VERBOSE (engine, "new timebase master: %s\n", | |||
client->control->name); | |||
} | |||
@@ -236,6 +241,22 @@ jack_timebase_set (jack_engine_t *engine, | |||
return ret; | |||
} | |||
/* for client activation | |||
* | |||
* precondition: caller holds the graph lock. */ | |||
void | |||
jack_transport_activate (jack_engine_t *engine, jack_client_internal_t *client) | |||
{ | |||
if (client->control->is_slowsync) { | |||
engine->control->sync_clients++; | |||
jack_sync_poll_new (engine, client); | |||
} | |||
if (client->control->is_timebase) { | |||
client->control->timebase_new = 1; | |||
} | |||
} | |||
/* for engine initialization */ | |||
void | |||
jack_transport_init (jack_engine_t *engine) | |||
@@ -260,7 +281,7 @@ jack_transport_init (jack_engine_t *engine) | |||
ectl->sync_time_left = 0; | |||
} | |||
/* when any client exits the graph | |||
/* when any client exits the graph (either dead or not active) | |||
* | |||
* precondition: caller holds the graph lock */ | |||
void | |||
@@ -268,15 +289,22 @@ jack_transport_client_exit (jack_engine_t *engine, | |||
jack_client_internal_t *client) | |||
{ | |||
if (client == engine->timebase_client) { | |||
engine->timebase_client->control->is_timebase = 0; | |||
engine->timebase_client = NULL; | |||
if (client->control->dead) { | |||
engine->timebase_client->control->is_timebase = 0; | |||
engine->timebase_client->control->timebase_new = 0; | |||
engine->timebase_client = NULL; | |||
VERBOSE (engine, "timebase master exit\n"); | |||
} | |||
engine->control->current_time.valid = 0; | |||
engine->control->pending_time.valid = 0; | |||
VERBOSE (engine, "timebase master exit\n"); | |||
} | |||
if (client->control->is_slowsync) | |||
if (client->control->is_slowsync) { | |||
jack_sync_poll_exit(engine, client); | |||
engine->control->sync_clients--; | |||
if (client->control->dead) | |||
client->control->is_slowsync = 0; | |||
} | |||
} | |||
/* when a new client is being created */ | |||
@@ -284,6 +312,7 @@ void | |||
jack_transport_client_new (jack_client_internal_t *client) | |||
{ | |||
client->control->is_timebase = 0; | |||
client->control->timebase_new = 0; | |||
client->control->is_slowsync = 0; | |||
client->control->sync_poll = 0; | |||
client->control->sync_new = 0; | |||
@@ -307,6 +336,9 @@ jack_transport_client_reset_sync (jack_engine_t *engine, | |||
if (client && (client->control->is_slowsync)) { | |||
jack_sync_poll_exit(engine, client); | |||
client->control->is_slowsync = 0; | |||
if (client->control->active) | |||
engine->control->sync_clients--; | |||
ret = 0; | |||
} else | |||
ret = EINVAL; | |||
@@ -332,11 +364,13 @@ jack_transport_client_set_sync (jack_engine_t *engine, | |||
if (client) { | |||
if (!client->control->is_slowsync) { | |||
client->control->is_slowsync = 1; | |||
engine->control->sync_clients++; | |||
if (client->control->active) | |||
engine->control->sync_clients++; | |||
} | |||
/* force poll of the new slow-sync client */ | |||
jack_sync_poll_new (engine, client); | |||
/* force poll of the new slow-sync client, if active */ | |||
if (client->control->active) | |||
jack_sync_poll_new (engine, client); | |||
ret = 0; | |||
} else | |||
ret = EINVAL; | |||
@@ -23,6 +23,8 @@ int jack_timebase_reset (jack_engine_t *engine, | |||
jack_client_id_t client_id); | |||
int jack_timebase_set (jack_engine_t *engine, | |||
jack_client_id_t client_id, int conditional); | |||
void jack_transport_activate (jack_engine_t *engine, | |||
jack_client_internal_t *client); | |||
void jack_transport_init (jack_engine_t *engine); | |||
void jack_transport_client_exit (jack_engine_t *engine, | |||
jack_client_internal_t *client); | |||
@@ -29,7 +29,6 @@ struct _jack_client { | |||
void *on_shutdown_arg; | |||
char thread_ok : 1; | |||
char first_active : 1; | |||
char new_timebase : 1; | |||
pthread_t thread_id; | |||
#if defined(__APPLE__) && defined(__POWERPC__) | |||
@@ -175,8 +175,8 @@ jack_call_timebase_master (jack_client_t *client) | |||
* critical section; timebase_cb is not. */ | |||
if (control->is_timebase) { | |||
if (client->new_timebase) { /* first callback? */ | |||
client->new_timebase = 0; | |||
if (control->timebase_new) { /* first callback? */ | |||
control->timebase_new = 0; | |||
new_pos = 1; | |||
} | |||
@@ -194,7 +194,6 @@ jack_call_timebase_master (jack_client_t *client) | |||
} else { | |||
/* another master took over, so resign */ | |||
client->new_timebase = 0; | |||
control->timebase_cb = NULL; | |||
control->timebase_arg = NULL; | |||
} | |||
@@ -300,7 +299,6 @@ jack_release_timebase (jack_client_t *client) | |||
rc = jack_client_deliver_request (client, &req); | |||
if (rc == 0) { | |||
client->new_timebase = 0; | |||
ctl->timebase_cb = NULL; | |||
ctl->timebase_arg = NULL; | |||
} | |||
@@ -354,7 +352,6 @@ jack_set_timebase_callback (jack_client_t *client, int conditional, | |||
rc = jack_client_deliver_request (client, &req); | |||
if (rc == 0) { | |||
client->new_timebase = 1; | |||
ctl->timebase_arg = arg; | |||
ctl->timebase_cb = timebase_cb; | |||
} | |||