From 866c16af4f2c8f49801bf0213aac9232e96f2d15 Mon Sep 17 00:00:00 2001 From: joq Date: Tue, 16 Dec 2003 03:28:40 +0000 Subject: [PATCH] [0.92.0] fix transport bug:000023 git-svn-id: svn+ssh://jackaudio.org/trunk/jack@589 0c269be4-1314-0410-8aa9-9f06e86f4224 --- configure.in | 6 ++-- example-clients/transport.c | 16 ++++++++++ jack/internal.h | 3 +- jackd/engine.c | 20 ++++++------- jackd/transengine.c | 60 +++++++++++++++++++++++++++++-------- jackd/transengine.h | 2 ++ libjack/local.h | 1 - libjack/transclient.c | 7 ++--- 8 files changed, 82 insertions(+), 33 deletions(-) diff --git a/configure.in b/configure.in index b90ab9e..aef3c33 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/example-clients/transport.c b/example-clients/transport.c index ae847f3..3d33e16 100644 --- a/example-clients/transport.c +++ b/example-clients/transport.c @@ -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 []"}, {"locate", com_locate, "Locate to frame "}, {"master", com_master, "Become timebase master " diff --git a/jack/internal.h b/jack/internal.h index 9cc4c67..2a0863e 100644 --- a/jack/internal.h +++ b/jack/internal.h @@ -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 */ diff --git a/jackd/engine.c b/jackd/engine.c index f8ba908..3e80e08 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -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; } } diff --git a/jackd/transengine.c b/jackd/transengine.c index 5d19d64..a355b1a 100644 --- a/jackd/transengine.c +++ b/jackd/transengine.c @@ -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; diff --git a/jackd/transengine.h b/jackd/transengine.h index c23263d..9bd238d 100644 --- a/jackd/transengine.h +++ b/jackd/transengine.h @@ -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); diff --git a/libjack/local.h b/libjack/local.h index 5518b0f..4336e85 100644 --- a/libjack/local.h +++ b/libjack/local.h @@ -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__) diff --git a/libjack/transclient.c b/libjack/transclient.c index e9abeff..6a6f0d1 100644 --- a/libjack/transclient.c +++ b/libjack/transclient.c @@ -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; }