Browse Source

[0.92.0] fix transport bug:000023

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@589 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
joq 21 years ago
parent
commit
866c16af4f
8 changed files with 82 additions and 33 deletions
  1. +3
    -3
      configure.in
  2. +16
    -0
      example-clients/transport.c
  3. +2
    -1
      jack/internal.h
  4. +10
    -10
      jackd/engine.c
  5. +47
    -13
      jackd/transengine.c
  6. +2
    -0
      jackd/transengine.h
  7. +0
    -1
      libjack/local.h
  8. +2
    -5
      libjack/transclient.c

+ 3
- 3
configure.in View File

@@ -14,8 +14,8 @@ dnl micro version = incremented when implementation-only
dnl changes are made dnl changes are made
dnl --- dnl ---
JACK_MAJOR_VERSION=0 JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=91
JACK_MICRO_VERSION=4
JACK_MINOR_VERSION=92
JACK_MICRO_VERSION=0


dnl --- dnl ---
dnl HOWTO: updating the jack protocal version 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 that would break applications linked with an older
dnl version of libjack. dnl version of libjack.
dnl --- dnl ---
JACK_PROTOCOL_VERSION=11
JACK_PROTOCOL_VERSION=12


dnl --- dnl ---
dnl HOWTO: updating the libjack interface version dnl HOWTO: updating the libjack interface version


+ 16
- 0
example-clients/transport.c View File

@@ -126,6 +126,20 @@ void signal_handler(int sig)


/* Command functions: see commands[] table following. */ /* 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) void com_exit(char *arg)
{ {
done = 1; done = 1;
@@ -203,7 +217,9 @@ typedef struct {


/* command table must be in alphabetical order */ /* command table must be in alphabetical order */
command_t commands[] = { command_t commands[] = {
{"activate", com_activate, "Call jack_activate()"},
{"exit", com_exit, "Exit transport program"}, {"exit", com_exit, "Exit transport program"},
{"deactivate", com_deactivate, "Call jack_deactivate()"},
{"help", com_help, "Display help text [<command>]"}, {"help", com_help, "Display help text [<command>]"},
{"locate", com_locate, "Locate to frame <position>"}, {"locate", com_locate, "Locate to frame <position>"},
{"master", com_master, "Become timebase master " {"master", com_master, "Become timebase master "


+ 2
- 1
jack/internal.h View File

@@ -96,7 +96,7 @@ typedef struct {
int8_t new_pos; /* new position this cycle */ int8_t new_pos; /* new position this cycle */
int8_t pending_pos; /* new position request pending */ int8_t pending_pos; /* new position request pending */
jack_nframes_t pending_frame; /* pending frame number */ 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 */ uint32_t sync_remain; /* number of them with sync_poll */
jack_time_t sync_timeout; jack_time_t sync_timeout;
jack_time_t sync_time_left; jack_time_t sync_time_left;
@@ -170,6 +170,7 @@ typedef volatile struct {
volatile int8_t dead : 1; /* r/w: engine */ volatile int8_t dead : 1; /* r/w: engine */
volatile int8_t timed_out : 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 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 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_poll : 1; /* w: engine and client, r: engine */
volatile int8_t sync_new : 1; /* w: engine and client, r: engine */ volatile int8_t sync_new : 1; /* w: engine and client, r: engine */


+ 10
- 10
jackd/engine.c View File

@@ -1447,12 +1447,13 @@ jack_client_activate (jack_engine_t *engine, jack_client_id_t id)
client = (jack_client_internal_t *) node->data; client = (jack_client_internal_t *) node->data;
client->control->active = TRUE; 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, jack_get_fifo_fd (engine,
++engine->external_client_cnt); ++engine->external_client_cnt);
@@ -1476,6 +1477,8 @@ jack_client_do_deactivate (jack_engine_t *engine,
* cleared all connections held by client. */ * cleared all connections held by client. */
client->control->active = FALSE; client->control->active = FALSE;


jack_transport_client_exit (engine, client);

if (!jack_client_is_internal (client) && if (!jack_client_is_internal (client) &&
engine->external_client_cnt > 0) { engine->external_client_cnt > 0) {
engine->external_client_cnt--; engine->external_client_cnt--;
@@ -1527,16 +1530,13 @@ jack_client_deactivate (jack_engine_t *engine, jack_client_id_t id)
JSList *portnode; JSList *portnode;
jack_port_internal_t *port; jack_port_internal_t *port;


jack_transport_client_exit (engine, client);
for (portnode = client->ports; portnode; for (portnode = client->ports; portnode;
portnode = jack_slist_next (portnode)) { portnode = jack_slist_next (portnode)) {
port = (jack_port_internal_t *) portnode->data; port = (jack_port_internal_t *) portnode->data;
jack_port_clear_connections (engine, port); jack_port_clear_connections (engine, port);
} }


ret = jack_client_do_deactivate (engine, node->data,
TRUE);
ret = jack_client_do_deactivate (engine, client, TRUE);
break; break;
} }
} }


+ 47
- 13
jackd/transengine.c View File

@@ -68,8 +68,6 @@ jack_sync_poll_exit (jack_engine_t *engine, jack_client_internal_t *client)
VERBOSE (engine, "sync poll interrupted for client %" VERBOSE (engine, "sync poll interrupted for client %"
PRIu32 "\n", client->control->id); PRIu32 "\n", client->control->id);
} }
client->control->is_slowsync = 0;
engine->control->sync_clients--;
} }


/* stop polling all the slow-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 *client =
(jack_client_internal_t *) node->data; (jack_client_internal_t *) node->data;
if (client->control->is_slowsync && if (client->control->is_slowsync &&
client->control->active &&
client->control->sync_poll) { client->control->sync_poll) {
client->control->sync_poll = 0; client->control->sync_poll = 0;
poll_count++; poll_count++;
@@ -114,7 +113,8 @@ jack_sync_poll_start (jack_engine_t *engine)
for (node = engine->clients; node; node = jack_slist_next (node)) { for (node = engine->clients; node; node = jack_slist_next (node)) {
jack_client_internal_t *client = jack_client_internal_t *client =
(jack_client_internal_t *) node->data; (jack_client_internal_t *) node->data;
if (client->control->is_slowsync) {
if (client->control->is_slowsync &&
client->control->active) {
client->control->sync_poll = 1; client->control->sync_poll = 1;
sync_count++; sync_count++;
} }
@@ -122,7 +122,7 @@ jack_sync_poll_start (jack_engine_t *engine)


//JOQ: check invariant for debugging... //JOQ: check invariant for debugging...
assert (sync_count == engine->control->sync_clients); 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; engine->control->sync_time_left = engine->control->sync_timeout;
VERBOSE (engine, "transport Starting, sync poll of %" PRIu32 VERBOSE (engine, "transport Starting, sync poll of %" PRIu32
" clients for %8.6f secs\n", engine->control->sync_remain, " 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); client = jack_client_internal_by_id (engine, client_id);
if (client && (client == engine->timebase_client)) { if (client && (client == engine->timebase_client)) {
client->control->is_timebase = 0; client->control->is_timebase = 0;
client->control->timebase_new = 0;
engine->timebase_client = NULL; engine->timebase_client = NULL;
ectl->pending_time.valid = 0; ectl->pending_time.valid = 0;
VERBOSE (engine, "%s resigned as timebase master\n", VERBOSE (engine, "%s resigned as timebase master\n",
@@ -223,10 +224,14 @@ jack_timebase_set (jack_engine_t *engine,


} else { } else {


if (engine->timebase_client)
if (engine->timebase_client) {
engine->timebase_client->control->is_timebase = 0; engine->timebase_client->control->is_timebase = 0;
engine->timebase_client->control->timebase_new = 0;
}
engine->timebase_client = client; engine->timebase_client = client;
client->control->is_timebase = 1; client->control->is_timebase = 1;
if (client->control->active)
client->control->timebase_new = 1;
VERBOSE (engine, "new timebase master: %s\n", VERBOSE (engine, "new timebase master: %s\n",
client->control->name); client->control->name);
} }
@@ -236,6 +241,22 @@ jack_timebase_set (jack_engine_t *engine,
return ret; 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 */ /* for engine initialization */
void void
jack_transport_init (jack_engine_t *engine) jack_transport_init (jack_engine_t *engine)
@@ -260,7 +281,7 @@ jack_transport_init (jack_engine_t *engine)
ectl->sync_time_left = 0; 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 */ * precondition: caller holds the graph lock */
void void
@@ -268,15 +289,22 @@ jack_transport_client_exit (jack_engine_t *engine,
jack_client_internal_t *client) jack_client_internal_t *client)
{ {
if (client == engine->timebase_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->current_time.valid = 0;
engine->control->pending_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); 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 */ /* when a new client is being created */
@@ -284,6 +312,7 @@ void
jack_transport_client_new (jack_client_internal_t *client) jack_transport_client_new (jack_client_internal_t *client)
{ {
client->control->is_timebase = 0; client->control->is_timebase = 0;
client->control->timebase_new = 0;
client->control->is_slowsync = 0; client->control->is_slowsync = 0;
client->control->sync_poll = 0; client->control->sync_poll = 0;
client->control->sync_new = 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)) { if (client && (client->control->is_slowsync)) {
jack_sync_poll_exit(engine, client); jack_sync_poll_exit(engine, client);
client->control->is_slowsync = 0;
if (client->control->active)
engine->control->sync_clients--;
ret = 0; ret = 0;
} else } else
ret = EINVAL; ret = EINVAL;
@@ -332,11 +364,13 @@ jack_transport_client_set_sync (jack_engine_t *engine,
if (client) { if (client) {
if (!client->control->is_slowsync) { if (!client->control->is_slowsync) {
client->control->is_slowsync = 1; 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; ret = 0;
} else } else
ret = EINVAL; ret = EINVAL;


+ 2
- 0
jackd/transengine.h View File

@@ -23,6 +23,8 @@ int jack_timebase_reset (jack_engine_t *engine,
jack_client_id_t client_id); jack_client_id_t client_id);
int jack_timebase_set (jack_engine_t *engine, int jack_timebase_set (jack_engine_t *engine,
jack_client_id_t client_id, int conditional); 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_init (jack_engine_t *engine);
void jack_transport_client_exit (jack_engine_t *engine, void jack_transport_client_exit (jack_engine_t *engine,
jack_client_internal_t *client); jack_client_internal_t *client);


+ 0
- 1
libjack/local.h View File

@@ -29,7 +29,6 @@ struct _jack_client {
void *on_shutdown_arg; void *on_shutdown_arg;
char thread_ok : 1; char thread_ok : 1;
char first_active : 1; char first_active : 1;
char new_timebase : 1;
pthread_t thread_id; pthread_t thread_id;
#if defined(__APPLE__) && defined(__POWERPC__) #if defined(__APPLE__) && defined(__POWERPC__)


+ 2
- 5
libjack/transclient.c View File

@@ -175,8 +175,8 @@ jack_call_timebase_master (jack_client_t *client)
* critical section; timebase_cb is not. */ * critical section; timebase_cb is not. */
if (control->is_timebase) { 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; new_pos = 1;
} }


@@ -194,7 +194,6 @@ jack_call_timebase_master (jack_client_t *client)
} else { } else {


/* another master took over, so resign */ /* another master took over, so resign */
client->new_timebase = 0;
control->timebase_cb = NULL; control->timebase_cb = NULL;
control->timebase_arg = NULL; control->timebase_arg = NULL;
} }
@@ -300,7 +299,6 @@ jack_release_timebase (jack_client_t *client)


rc = jack_client_deliver_request (client, &req); rc = jack_client_deliver_request (client, &req);
if (rc == 0) { if (rc == 0) {
client->new_timebase = 0;
ctl->timebase_cb = NULL; ctl->timebase_cb = NULL;
ctl->timebase_arg = 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); rc = jack_client_deliver_request (client, &req);
if (rc == 0) { if (rc == 0) {
client->new_timebase = 1;
ctl->timebase_arg = arg; ctl->timebase_arg = arg;
ctl->timebase_cb = timebase_cb; ctl->timebase_cb = timebase_cb;
} }


Loading…
Cancel
Save