Browse Source

fix export of pointers into JACK API headers, thus allowing a 64 bit JACK server to support 32 bit clients and vice versa (work done primarily by Torben, with a few cleanups from Paul)

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@3000 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.115.6
paul 17 years ago
parent
commit
69039cae1c
9 changed files with 348 additions and 210 deletions
  1. +2
    -1
      drivers/alsa/alsa_driver.c
  2. +102
    -64
      jack/internal.h
  3. +17
    -1
      jack/transport.h
  4. +51
    -32
      jackd/clientengine.c
  5. +32
    -26
      jackd/engine.c
  6. +12
    -4
      jackd/transengine.c
  7. +78
    -68
      libjack/client.c
  8. +34
    -0
      libjack/local.h
  9. +20
    -14
      libjack/transclient.c

+ 2
- 1
drivers/alsa/alsa_driver.c View File

@@ -532,12 +532,13 @@ alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name,
return -1;
}
jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name);
#if 0
if (!jack_power_of_two(driver->frames_per_cycle)) {
jack_error("JACK: frames must be a power of two "
"(64, 512, 1024, ...)\n");
return -1;
}
#endif

if ((err = snd_pcm_hw_params_set_buffer_size (handle, hw_params,
*nperiodsp *


+ 102
- 64
jack/internal.h View File

@@ -34,6 +34,21 @@
#include <sys/types.h>
#include <sys/time.h>

#ifndef POST_PACKED_STRUCTURE
#ifdef __GNUC__
/* POST_PACKED_STRUCTURE needs to be a macro which
expands into a compiler directive. The directive must
tell the compiler to arrange the preceding structure
declaration so that it is packed on byte-boundaries rather
than use the natural alignment of the processor and/or
compiler.
*/
#define POST_PACKED_STRUCTURE __attribute__((__packed__))
#else
/* Add other things here for non-gcc platforms */
#endif
#endif

/* Needed by <sysdeps/time.h> */
extern void jack_error (const char *fmt, ...);

@@ -136,7 +151,7 @@ typedef struct {
int32_t reset_pending; /* xrun happened, deal with it */
float filter_coefficient; /* set once, never altered */

} jack_frame_timer_t;
} POST_PACKED_STRUCTURE jack_frame_timer_t;

/* JACK engine shared memory data structure. */
typedef struct {
@@ -175,7 +190,7 @@ typedef struct {
jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES];
jack_port_shared_t ports[0];

} jack_control_t;
} POST_PACKED_STRUCTURE jack_control_t;

typedef enum {
BufferSizeChange,
@@ -206,7 +221,7 @@ typedef struct {
jack_port_type_id_t ptid;
jack_port_id_t other_id;
} y;
} jack_event_t;
} POST_PACKED_STRUCTURE jack_event_t;

typedef enum {
ClientInternal, /* connect request just names .so */
@@ -245,48 +260,28 @@ typedef volatile struct {
volatile uint64_t finished_at;
volatile int32_t last_status; /* w: client, r: engine and client */

/* JOQ: all these pointers are trouble for 32/64 compatibility,
* they should move to non-shared memory.
/* indicators for whether callbacks have been set for this client.
We do not include ptrs to the callbacks here (or their arguments)
so that we can avoid 32/64 bit pointer size mismatches between
the jack server and a client. The pointers are in the client-
local structure which is part of the libjack compiled for
either 32 bit or 64 bit clients.
*/

/* callbacks
*/
JackProcessCallback process;
void *process_arg;
JackThreadInitCallback thread_init;
void *thread_init_arg;
JackBufferSizeCallback bufsize;
void *bufsize_arg;
JackSampleRateCallback srate;
void *srate_arg;
JackPortRegistrationCallback port_register;
void *port_register_arg;
JackPortConnectCallback port_connect;
void *port_connect_arg;
JackGraphOrderCallback graph_order;
void *graph_order_arg;
JackXRunCallback xrun;
void *xrun_arg;
JackSyncCallback sync_cb;
void *sync_arg;
JackTimebaseCallback timebase_cb;
void *timebase_arg;
JackFreewheelCallback freewheel_cb;
void *freewheel_arg;
JackClientRegistrationCallback client_register;
void *client_register_arg;
JackThreadCallback thread_cb;
void *thread_cb_arg;

/* external clients: set by libjack
* internal clients: set by engine */
int (*deliver_request)(void*, jack_request_t*); /* JOQ: 64/32 bug! */
void *deliver_arg;

/* for engine use only */
void *private_client;

} jack_client_control_t;
volatile uint8_t process_cbset;
volatile uint8_t thread_init_cbset;
volatile uint8_t bufsize_cbset;
volatile uint8_t srate_cbset;
volatile uint8_t port_register_cbset;
volatile uint8_t port_connect_cbset;
volatile uint8_t graph_order_cbset;
volatile uint8_t xrun_cbset;
volatile uint8_t sync_cb_cbset;
volatile uint8_t timebase_cb_cbset;
volatile uint8_t freewheel_cb_cbset;
volatile uint8_t client_register_cbset;
volatile uint8_t thread_cb_cbset;

} POST_PACKED_STRUCTURE jack_client_control_t;

typedef struct {
@@ -299,14 +294,14 @@ typedef struct {
char object_path[PATH_MAX+1];
char object_data[1024];

} jack_client_connect_request_t;
} POST_PACKED_STRUCTURE jack_client_connect_request_t;

typedef struct {

jack_status_t status;

jack_shm_info_t client_shm;
jack_shm_info_t engine_shm;
jack_shm_registry_index_t client_shm_index;
jack_shm_registry_index_t engine_shm_index;

char fifo_prefix[PATH_MAX+1];

@@ -315,24 +310,29 @@ typedef struct {

char name[JACK_CLIENT_NAME_SIZE]; /* unique name, if assigned */

/* these two are valid only for internal clients */
jack_client_control_t *client_control;
jack_control_t *engine_control;
/* these two are valid only for internal clients, and thus
are exempt from the requirement that we not export
pointers back to clients. an internal client must
necessarily match the host, so 32/64 bit issues
do not apply to these pointers.
*/
jack_client_control_t* client_control;
jack_control_t* engine_control;

#ifdef JACK_USE_MACH_THREADS
/* specific resources for server/client real-time thread communication */
int32_t portnum;
#endif

} jack_client_connect_result_t;
} POST_PACKED_STRUCTURE jack_client_connect_result_t;

typedef struct {
jack_client_id_t client_id;
} jack_client_connect_ack_request_t;
} POST_PACKED_STRUCTURE jack_client_connect_ack_request_t;

typedef struct {
int8_t status;
} jack_client_connect_ack_result_t;
} POST_PACKED_STRUCTURE jack_client_connect_ack_result_t;

typedef enum {
RegisterPort = 1,
@@ -363,7 +363,8 @@ typedef enum {

struct _jack_request {
RequestType type;
//RequestType type;
uint32_t type;
union {
struct {
char name[JACK_PORT_NAME_SIZE];
@@ -372,33 +373,35 @@ struct _jack_request {
jack_shmsize_t buffer_size;
jack_port_id_t port_id;
jack_client_id_t client_id;
} port_info;
} POST_PACKED_STRUCTURE port_info;
struct {
char source_port[JACK_PORT_NAME_SIZE];
char destination_port[JACK_PORT_NAME_SIZE];
} connect;
} POST_PACKED_STRUCTURE connect;
struct {
int32_t nports;
const char **ports; /* JOQ: 32/64 problem? */
} port_connections;
//const char **ports; /* JOQ: 32/64 problem? */
uint64_t ports;
} POST_PACKED_STRUCTURE port_connections;
struct {
jack_client_id_t client_id;
int32_t conditional;
} timebase;
} POST_PACKED_STRUCTURE timebase;
struct {
jack_options_t options;
//jack_options_t options;
uint32_t options;
jack_client_id_t id;
char name[JACK_CLIENT_NAME_SIZE];
char path[PATH_MAX+1];
char init[JACK_LOAD_INIT_LIMIT];
} intclient;
} POST_PACKED_STRUCTURE intclient;
jack_client_id_t client_id;
jack_nframes_t nframes;
jack_time_t timeout;
pid_t cap_pid;
} x;
} POST_PACKED_STRUCTURE x;
int32_t status;
};
} POST_PACKED_STRUCTURE;

/* Per-client structure allocated in the server's address space.
* It's here because its not part of the engine structure.
@@ -432,7 +435,42 @@ typedef struct _jack_client_internal {
int running;
int portnum;
#endif /* JACK_USE_MACH_THREADS */
#if 0
/* callbacks
*/
JackProcessCallback process;
void *process_arg;
JackThreadInitCallback thread_init;
void *thread_init_arg;
JackBufferSizeCallback bufsize;
void *bufsize_arg;
JackSampleRateCallback srate;
void *srate_arg;
JackPortRegistrationCallback port_register;
void *port_register_arg;
JackPortConnectCallback port_connect;
void *port_connect_arg;
JackGraphOrderCallback graph_order;
void *graph_order_arg;
JackXRunCallback xrun;
void *xrun_arg;
JackSyncCallback sync_cb;
void *sync_arg;
JackTimebaseCallback timebase_cb;
void *timebase_arg;
JackFreewheelCallback freewheel_cb;
void *freewheel_arg;
JackClientRegistrationCallback client_register;
void *client_register_arg;
JackThreadCallback thread_cb;
void *thread_cb_arg;
#endif
/* external clients: set by libjack
* internal clients: set by engine */
//int (*deliver_request)(void*, jack_request_t*); /* JOQ: 64/32 bug! */
//void *deliver_arg;
jack_client_t *private_client;
} jack_client_internal_t;

typedef struct _jack_thread_arg {


+ 17
- 1
jack/transport.h View File

@@ -27,6 +27,22 @@ extern "C" {

#include <jack/types.h>

#ifndef POST_PACKED_STRUCTURE
#ifdef __GNUC__
/* POST_PACKED_STRUCTURE needs to be a macro which
expands into a compiler directive. The directive must
tell the compiler to arrange the preceding structure
declaration so that it is packed on byte-boundaries rather
than use the natural alignment of the processor and/or
compiler.
*/
#define POST_PACKED_STRUCTURE __attribute__((__packed__))
#else
/* Add other things here for non-gcc platforms */
#endif
#endif


/**
* Transport states.
*/
@@ -127,7 +143,7 @@ typedef struct {
/* When (unique_1 == unique_2) the contents are consistent. */
jack_unique_t unique_2; /**< unique ID */

} jack_position_t;
} POST_PACKED_STRUCTURE jack_position_t;

/**
* Called by the timebase master to release itself from that


+ 51
- 32
jackd/clientengine.c View File

@@ -38,6 +38,8 @@
#include "clientengine.h"
#include "transengine.h"

#include "libjack/local.h"

static void
jack_client_disconnect_ports (jack_engine_t *engine,
jack_client_internal_t *client)
@@ -318,7 +320,7 @@ jack_client_unload (jack_client_internal_t *client)
{
if (client->handle) {
if (client->finish) {
client->finish (client->control->process_arg);
client->finish (client->private_client->process_arg);
}
dlclose (client->handle);
}
@@ -516,25 +518,38 @@ jack_setup_client_control (jack_engine_t *engine, int fd,
client->subgraph_start_fd = -1;
client->subgraph_wait_fd = -1;

client->control->process = NULL;
client->control->process_arg = NULL;
client->control->bufsize = NULL;
client->control->bufsize_arg = NULL;
client->control->srate = NULL;
client->control->srate_arg = NULL;
client->control->xrun = NULL;
client->control->xrun_arg = NULL;
client->control->port_register = NULL;
client->control->port_register_arg = NULL;
client->control->port_connect = NULL;
client->control->port_connect_arg = NULL;
client->control->graph_order = NULL;
client->control->graph_order_arg = NULL;
client->control->client_register = NULL;
client->control->client_register_arg = NULL;
client->control->thread_cb = NULL;
client->control->thread_cb_arg = NULL;

client->control->process_cbset = FALSE;
client->control->bufsize_cbset = FALSE;
client->control->srate_cbset = FALSE;
client->control->xrun_cbset = FALSE;
client->control->port_register_cbset = FALSE;
client->control->port_connect_cbset = FALSE;
client->control->graph_order_cbset = FALSE;
client->control->client_register_cbset = FALSE;
client->control->thread_cb_cbset = FALSE;

#if 0
if (type != ClientExternal) {
client->process = NULL;
client->process_arg = NULL;
client->bufsize = NULL;
client->bufsize_arg = NULL;
client->srate = NULL;
client->srate_arg = NULL;
client->xrun = NULL;
client->xrun_arg = NULL;
client->port_register = NULL;
client->port_register_arg = NULL;
client->port_connect = NULL;
client->port_connect_arg = NULL;
client->graph_order = NULL;
client->graph_order_arg = NULL;
client->client_register = NULL;
client->client_register_arg = NULL;
client->thread_cb = NULL;
client->thread_cb_arg = NULL;
}
#endif
jack_transport_client_new (client);
#ifdef JACK_USE_MACH_THREADS
@@ -586,12 +601,22 @@ setup_client (jack_engine_t *engine, ClientType type, char *name,

if (jack_client_is_internal(client)) {

// XXX: do i need to lock the graph here ?
// i moved this one up in the init process, lets see what happens.

/* Internal clients need to make regular JACK API
* calls, which need a jack_client_t structure.
* Create one here.
*/
client->private_client =
jack_client_alloc_internal (client->control, engine);

/* Set up the pointers necessary for the request
* system to work. The client is in the same address
* space */

client->control->deliver_request = internal_client_request;
client->control->deliver_arg = engine;
client->private_client->deliver_request = internal_client_request;
client->private_client->deliver_arg = engine;
}

/* add new client to the clients list */
@@ -601,12 +626,6 @@ setup_client (jack_engine_t *engine, ClientType type, char *name,
if (jack_client_is_internal(client)) {

/* Internal clients need to make regular JACK API
* calls, which need a jack_client_t structure.
* Create one here.
*/
client->control->private_client =
jack_client_alloc_internal (client->control, engine);

jack_unlock_graph (engine);

@@ -616,7 +635,7 @@ setup_client (jack_engine_t *engine, ClientType type, char *name,
if (client->control->type == ClientInternal) {

pthread_mutex_unlock (&engine->request_lock);
if (client->initialize (client->control->private_client,
if (client->initialize (client->private_client,
object_data)) {

/* failed: clean up client data */
@@ -735,8 +754,8 @@ jack_client_create (jack_engine_t *engine, int client_fd)
res.status |= JackFailure; /* just making sure */
return -1;
}
res.client_shm = client->control_shm;
res.engine_shm = engine->control_shm;
res.client_shm_index = client->control_shm.index;
res.engine_shm_index = engine->control_shm.index;
res.realtime = engine->control->real_time;
res.realtime_priority = engine->rtpriority - 1;
strncpy (res.name, req.name, sizeof(res.name));
@@ -880,7 +899,7 @@ jack_client_delete (jack_engine_t *engine, jack_client_internal_t *client)
if (jack_client_is_internal (client)) {

jack_client_unload (client);
free (client->control->private_client);
free (client->private_client);
free ((void *) client->control);

} else {


+ 32
- 26
jackd/engine.c View File

@@ -61,6 +61,8 @@
#include "clientengine.h"
#include "transengine.h"

#include "libjack/local.h"

typedef struct {

jack_port_internal_t *source;
@@ -581,17 +583,17 @@ jack_process_internal(jack_engine_t *engine, JSList *node,

/* XXX how to time out an internal client? */

if (ctl->sync_cb)
jack_call_sync_client (ctl->private_client);
if (ctl->sync_cb_cbset)
jack_call_sync_client (client->private_client);

if (ctl->process)
if (ctl->process (nframes, ctl->process_arg)) {
if (ctl->process_cbset)
if (client->private_client->process (nframes, client->private_client->process_arg)) {
jack_error ("internal client %s failed", ctl->name);
engine->process_errors++;
}

if (ctl->timebase_cb)
jack_call_timebase_master (ctl->private_client);
if (ctl->timebase_cb_cbset)
jack_call_timebase_master (client->private_client);
ctl->state = Finished;

@@ -1071,7 +1073,7 @@ jack_engine_load_driver (jack_engine_t *engine,
return -1;
}

if ((driver = info->initialize (client->control->private_client,
if ((driver = info->initialize (client->private_client,
driver_params)) == NULL) {
free (info);
return -1;
@@ -1401,6 +1403,8 @@ handle_external_client_request (jack_engine_t *engine, int fd)
} else {
jack_error ("cannot read request from client (%d/%d/%s)",
r, sizeof(req), strerror (errno));
// XXX: shouldnt we mark this client as error now ?

return -1;
}
}
@@ -2410,7 +2414,7 @@ jack_notify_all_port_interested_clients (jack_engine_t *engine, jack_client_id_t

for (node = engine->clients; node; node = jack_slist_next (node)) {
jack_client_internal_t* client = (jack_client_internal_t*) node->data;
if (src_client != client && dst_client != client && client->control->port_connect != NULL) {
if (src_client != client && dst_client != client && client->control->port_connect_cbset != FALSE) {
/* one of the ports belong to this client or it has a port connect callback */
jack_deliver_event (engine, client, &event);
@@ -2447,39 +2451,39 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client,
case PortConnected:
case PortDisconnected:
jack_client_handle_port_connection
(client->control->private_client, event);
(client->private_client, event);
break;

case BufferSizeChange:
jack_client_invalidate_port_buffers
(client->control->private_client);
(client->private_client);

if (client->control->bufsize) {
client->control->bufsize
if (client->control->bufsize_cbset) {
client->private_client->bufsize
(event->x.n,
client->control->bufsize_arg);
client->private_client->bufsize_arg);
}
break;

case SampleRateChange:
if (client->control->srate) {
client->control->srate
if (client->control->srate_cbset) {
client->private_client->srate
(event->x.n,
client->control->srate_arg);
client->private_client->srate_arg);
}
break;

case GraphReordered:
if (client->control->graph_order) {
client->control->graph_order
(client->control->graph_order_arg);
if (client->control->graph_order_cbset) {
client->private_client->graph_order
(client->private_client->graph_order_arg);
}
break;

case XRun:
if (client->control->xrun) {
client->control->xrun
(client->control->xrun_arg);
if (client->control->xrun_cbset) {
client->private_client->xrun
(client->private_client->xrun_arg);
}
break;

@@ -3134,7 +3138,7 @@ void jack_dump_configuration(jack_engine_t *engine, int take_lock)
++n,
ctl->name,
ctl->type,
ctl->process ? "yes" : "no",
ctl->process_cbset ? "yes" : "no",
client->subgraph_start_fd,
client->subgraph_wait_fd);

@@ -3940,7 +3944,9 @@ jack_do_get_port_connections (jack_engine_t *engine, jack_request_t *req,
* names. store in malloc'ed space,
* client frees
*/
req->x.port_connections.ports[i] =
char **ports = req->x.port_connections.ports;

ports[i] =
engine->control->ports[port_id].name;

} else {
@@ -3987,7 +3993,7 @@ jack_port_registration_notify (jack_engine_t *engine,
continue;
}

if (client->control->port_register) {
if (client->control->port_register_cbset) {
if (jack_deliver_event (engine, client, &event)) {
jack_error ("cannot send port registration"
" notification to %s (%s)",
@@ -4022,7 +4028,7 @@ jack_client_registration_notify (jack_engine_t *engine,
continue;
}

if (client->control->client_register) {
if (client->control->client_register_cbset) {
if (jack_deliver_event (engine, client, &event)) {
jack_error ("cannot send client registration"
" notification to %s (%s)",


+ 12
- 4
jackd/transengine.c View File

@@ -321,10 +321,18 @@ jack_transport_client_new (jack_client_internal_t *client)
client->control->active_slowsync = 0;
client->control->sync_poll = 0;
client->control->sync_new = 0;
client->control->sync_cb = NULL;
client->control->sync_arg = NULL;
client->control->timebase_cb = NULL;
client->control->timebase_arg = NULL;
client->control->sync_cb_cbset = FALSE;
client->control->timebase_cb_cbset = FALSE;

#if 0
if (client->control->type != ClientExternal) {
client->sync_cb = NULL;
client->sync_arg = NULL;
client->timebase_cb = NULL;
client->timebase_arg = NULL;
}
#endif
}

/* on ResetSyncClient request */


+ 78
- 68
libjack/client.c View File

@@ -273,7 +273,7 @@ jack_client_deliver_request (const jack_client_t *client, jack_request_t *req)
* the server.
*/

return client->control->deliver_request (client->control->deliver_arg,
return client->deliver_request (client->deliver_arg,
req);
}

@@ -454,10 +454,10 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)
}
}

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

return 0;
@@ -530,8 +530,8 @@ jack_handle_reorder (jack_client_t *client, jack_event_t *event)
execute it now.
*/

if (client->control->graph_order) {
client->control->graph_order (client->control->graph_order_arg);
if (client->control->graph_order_cbset) {
client->graph_order (client->graph_order_arg);
}

return 0;
@@ -1013,7 +1013,7 @@ jack_client_open_aux (const char *client_name,
}

/* attach the engine control/info block */
client->engine_shm = res.engine_shm;
client->engine_shm.index = res.engine_shm_index;
if (jack_attach_shm (&client->engine_shm)) {
jack_error ("cannot attached engine control shared memory"
" segment");
@@ -1026,7 +1026,7 @@ jack_client_open_aux (const char *client_name,
jack_set_clock_source (client->engine->clock_source);

/* now attach the client control block */
client->control_shm = res.client_shm;
client->control_shm.index = res.client_shm_index;
if (jack_attach_shm (&client->control_shm)) {
jack_error ("cannot attached client control shared memory"
" segment");
@@ -1056,8 +1056,8 @@ jack_client_open_aux (const char *client_name,
/* set up the client so that it does the right thing for an
* external client
*/
client->control->deliver_request = oop_client_deliver_request;
client->control->deliver_arg = client;
client->deliver_request = oop_client_deliver_request;
client->deliver_arg = client;

if ((ev_fd = server_event_connect (client, va.server_name)) < 0) {
goto fail;
@@ -1255,8 +1255,8 @@ jack_start_freewheel (jack_client_t* client)
#endif
}

if (control->freewheel_cb) {
control->freewheel_cb (1, control->freewheel_arg);
if (control->freewheel_cb_cbset) {
client->freewheel_cb (1, client->freewheel_arg);
}
}

@@ -1275,8 +1275,8 @@ jack_stop_freewheel (jack_client_t* client)
#endif
}

if (control->freewheel_cb) {
control->freewheel_cb (0, control->freewheel_arg);
if (control->freewheel_cb_cbset) {
client->freewheel_cb (0, client->freewheel_arg);
}
}

@@ -1334,34 +1334,34 @@ jack_client_process_events (jack_client_t* client)
port->type_info = &client->engine->port_types[port->shared->ptype_id];
}
}
if (control->port_register) {
control->port_register
if (control->port_register_cbset) {
client->port_register
(event.x.port_id, TRUE,
control->port_register_arg);
client->port_register_arg);
}
break;
case PortUnregistered:
if (control->port_register) {
control->port_register
if (control->port_register_cbset) {
client->port_register
(event.x.port_id, FALSE,
control->port_register_arg);
client->port_register_arg);
}
break;
case ClientRegistered:
if (control->client_register) {
control->client_register
if (control->client_register_cbset) {
client->client_register
(event.x.name, TRUE,
control->client_register_arg);
client->client_register_arg);
}
break;
case ClientUnregistered:
if (control->client_register) {
control->client_register
if (control->client_register_cbset) {
client->client_register
(event.x.name, FALSE,
control->client_register_arg);
client->client_register_arg);
}
break;
@@ -1377,25 +1377,25 @@ jack_client_process_events (jack_client_t* client)
case BufferSizeChange:
jack_client_invalidate_port_buffers (client);
if (control->bufsize) {
status = control->bufsize
if (control->bufsize_cbset) {
status = client->bufsize
(control->nframes,
control->bufsize_arg);
client->bufsize_arg);
}
break;
case SampleRateChange:
if (control->srate) {
status = control->srate
if (control->srate_cbset) {
status = client->srate
(control->nframes,
control->srate_arg);
client->srate_arg);
}
break;
case XRun:
if (control->xrun) {
status = control->xrun
(control->xrun_arg);
if (control->xrun_cbset) {
status = client->xrun
(client->xrun_arg);
}
break;
@@ -1583,7 +1583,7 @@ jack_thread_wait (jack_client_t* client, int status)

/* housekeeping/cleanup after data processing */

if (status == 0 && client->control->timebase_cb) {
if (status == 0 && client->control->timebase_cb_cbset) {
jack_call_timebase_master (client);
}
@@ -1621,7 +1621,7 @@ jack_thread_wait (jack_client_t* client, int status)
/* begin preemption checking */
CHECK_PREEMPTION (client->engine, TRUE);
if (client->control->sync_cb)
if (client->control->sync_cb_cbset)
jack_call_sync_client (client);

return client->control->nframes;
@@ -1644,7 +1644,7 @@ jack_nframes_t jack_cycle_wait (jack_client_t* client)
/* begin preemption checking */
CHECK_PREEMPTION (client->engine, TRUE);
if (client->control->sync_cb)
if (client->control->sync_cb_cbset)
jack_call_sync_client (client);

return client->control->nframes;
@@ -1658,7 +1658,7 @@ void jack_cycle_signal(jack_client_t* client, int status)

/* housekeeping/cleanup after data processing */

if (status == 0 && client->control->timebase_cb) {
if (status == 0 && client->control->timebase_cb_cbset) {
jack_call_timebase_master (client);
}
@@ -1701,9 +1701,9 @@ jack_client_thread_aux (void *arg)

DEBUG ("client thread is now running");

if (control->thread_init) {
if (control->thread_init_cbset) {
DEBUG ("calling client thread init callback");
control->thread_init (control->thread_init_arg);
client->thread_init (client->thread_init_arg);
}

/* wait for first wakeup from server */
@@ -1712,14 +1712,14 @@ jack_client_thread_aux (void *arg)

/* now run till we're done */

if (control->process) {
if (control->process_cbset) {

/* run process callback, then wait... ad-infinitum */

while (1) {
DEBUG("client calls process()");
int status = (control->process (control->nframes,
control->process_arg) ==
int status = (client->process (control->nframes,
client->process_arg) ==
control->nframes);
control->state = Finished;
DEBUG("client leaves process(), re-enters wait");
@@ -1745,7 +1745,7 @@ jack_client_thread (void *arg)
jack_client_t *client = (jack_client_t *) arg;
jack_client_control_t *control = client->control;
if (client->control->thread_cb) {
if (client->control->thread_cb_cbset) {
pthread_mutex_lock (&client_lock);
client->thread_ok = TRUE;
@@ -1756,7 +1756,7 @@ jack_client_thread (void *arg)
control->pid = getpid();
control->pgrp = getpgrp();

client->control->thread_cb(client->control->thread_cb_arg);
client->thread_cb(client->thread_cb_arg);
jack_client_thread_suicide(client);
} else {
jack_client_thread_aux(arg);
@@ -2232,8 +2232,9 @@ jack_set_graph_order_callback (jack_client_t *client,
jack_error ("You cannot set callbacks on an active client.");
return -1;
}
client->control->graph_order = callback;
client->control->graph_order_arg = arg;
client->graph_order = callback;
client->graph_order_arg = arg;
client->control->graph_order_cbset = (callback != NULL);
return 0;
}

@@ -2245,8 +2246,9 @@ int jack_set_xrun_callback (jack_client_t *client,
return -1;
}

client->control->xrun = callback;
client->control->xrun_arg = arg;
client->xrun = callback;
client->xrun_arg = arg;
client->control->xrun_cbset = (callback != NULL);
return 0;
}

@@ -2260,13 +2262,14 @@ jack_set_process_callback (jack_client_t *client,
return -1;
}
if (client->control->thread_cb) {
if (client->control->thread_cb_cbset) {
jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
return -1;
}
client->control->process_arg = arg;
client->control->process = callback;
client->process_arg = arg;
client->process = callback;
client->control->process_cbset = (callback != NULL);
return 0;
}

@@ -2279,8 +2282,9 @@ jack_set_thread_init_callback (jack_client_t *client,
jack_error ("You cannot set callbacks on an active client.");
return -1;
}
client->control->thread_init_arg = arg;
client->control->thread_init = callback;
client->thread_init_arg = arg;
client->thread_init = callback;
client->control->thread_init_cbset = (callback != NULL);
return 0;
}

@@ -2292,8 +2296,9 @@ jack_set_freewheel_callback (jack_client_t *client,
jack_error ("You cannot set callbacks on an active client.");
return -1;
}
client->control->freewheel_arg = arg;
client->control->freewheel_cb = callback;
client->freewheel_arg = arg;
client->freewheel_cb = callback;
client->control->freewheel_cb_cbset = (callback != NULL);
return 0;
}

@@ -2301,8 +2306,9 @@ int
jack_set_buffer_size_callback (jack_client_t *client,
JackBufferSizeCallback callback, void *arg)
{
client->control->bufsize_arg = arg;
client->control->bufsize = callback;
client->bufsize_arg = arg;
client->bufsize = callback;
client->control->bufsize_cbset = (callback != NULL);
return 0;
}

@@ -2315,8 +2321,9 @@ jack_set_port_registration_callback(jack_client_t *client,
jack_error ("You cannot set callbacks on an active client.");
return -1;
}
client->control->port_register_arg = arg;
client->control->port_register = callback;
client->port_register_arg = arg;
client->port_register = callback;
client->control->port_register_cbset = (callback != NULL);
return 0;
}

@@ -2329,8 +2336,9 @@ jack_set_port_connect_callback(jack_client_t *client,
jack_error ("You cannot set callbacks on an active client.");
return -1;
}
client->control->port_connect_arg = arg;
client->control->port_connect = callback;
client->port_connect_arg = arg;
client->port_connect = callback;
client->control->port_connect_cbset = (callback != NULL);
return 0;
}

@@ -2343,8 +2351,9 @@ jack_set_client_registration_callback(jack_client_t *client,
jack_error ("You cannot set callbacks on an active client.");
return -1;
}
client->control->client_register_arg = arg;
client->control->client_register = callback;
client->client_register_arg = arg;
client->client_register = callback;
client->control->client_register_cbset = (callback != NULL);
return 0;
}

@@ -2356,13 +2365,14 @@ jack_set_process_thread(jack_client_t* client, JackThreadCallback callback, void
return -1;
}
if (client->control->process) {
if (client->control->process_cbset) {
jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
return -1;
}

client->control->thread_cb_arg = arg;
client->control->thread_cb = callback;
client->thread_cb_arg = arg;
client->thread_cb = callback;
client->control->thread_cb_cbset = (callback != NULL);
return 0;
}



+ 34
- 0
libjack/local.h View File

@@ -42,6 +42,40 @@ struct _jack_client {
char rt_thread_ok : 1;
#endif

/* callbacks
*/
JackProcessCallback process;
void *process_arg;
JackThreadInitCallback thread_init;
void *thread_init_arg;
JackBufferSizeCallback bufsize;
void *bufsize_arg;
JackSampleRateCallback srate;
void *srate_arg;
JackPortRegistrationCallback port_register;
void *port_register_arg;
JackPortConnectCallback port_connect;
void *port_connect_arg;
JackGraphOrderCallback graph_order;
void *graph_order_arg;
JackXRunCallback xrun;
void *xrun_arg;
JackSyncCallback sync_cb;
void *sync_arg;
JackTimebaseCallback timebase_cb;
void *timebase_arg;
JackFreewheelCallback freewheel_cb;
void *freewheel_arg;
JackClientRegistrationCallback client_register;
void *client_register_arg;
JackThreadCallback thread_cb;
void *thread_cb_arg;

/* external clients: set by libjack
* internal clients: set by engine */
int (*deliver_request)(void*, jack_request_t*); /* JOQ: 64/32 bug! */
void *deliver_arg;

};

extern int jack_client_deliver_request (const jack_client_t *client,


+ 20
- 14
libjack/transclient.c View File

@@ -135,9 +135,9 @@ jack_call_sync_client (jack_client_t *client)
if ((ectl->new_pos || control->sync_poll || control->sync_new) &&
control->active_slowsync) {

if (control->sync_cb (ectl->transport_state,
if (client->sync_cb (ectl->transport_state,
&ectl->current_time,
control->sync_arg)) {
client->sync_arg)) {

if (control->sync_poll) {
control->sync_poll = 0;
@@ -169,18 +169,19 @@ jack_call_timebase_master (jack_client_t *client)
if ((ectl->transport_state == JackTransportRolling) ||
new_pos) {

control->timebase_cb (ectl->transport_state,
client->timebase_cb (ectl->transport_state,
control->nframes,
&ectl->pending_time,
new_pos,
control->timebase_arg);
client->timebase_arg);
}

} else {

/* another master took over, so resign */
control->timebase_cb = NULL;
control->timebase_arg = NULL;
client->timebase_cb = NULL;
client->timebase_arg = NULL;
control->timebase_cb_cbset = FALSE;
}
}

@@ -309,8 +310,9 @@ jack_set_sample_rate_callback (jack_client_t *client,
jack_error ("You cannot set callbacks on an active client.");
return -1;
}
client->control->srate_arg = arg;
client->control->srate = callback;
client->srate_arg = arg;
client->srate = callback;
client->control->srate_cbset = (callback != NULL);

/* Now invoke it */

@@ -331,9 +333,11 @@ jack_release_timebase (jack_client_t *client)

rc = jack_client_deliver_request (client, &req);
if (rc == 0) {
ctl->timebase_cb = NULL;
ctl->timebase_arg = NULL;
client->timebase_cb = NULL;
client->timebase_arg = NULL;
ctl->timebase_cb_cbset = NULL;
}

return rc;
}

@@ -353,8 +357,9 @@ jack_set_sync_callback (jack_client_t *client,

rc = jack_client_deliver_request (client, &req);
if (rc == 0) {
ctl->sync_cb = sync_callback;
ctl->sync_arg = arg;
client->sync_cb = sync_callback;
client->sync_arg = arg;
ctl->sync_cb_cbset = TRUE;
}
return rc;
}
@@ -384,8 +389,9 @@ jack_set_timebase_callback (jack_client_t *client, int conditional,

rc = jack_client_deliver_request (client, &req);
if (rc == 0) {
ctl->timebase_arg = arg;
ctl->timebase_cb = timebase_cb;
client->timebase_arg = arg;
client->timebase_cb = timebase_cb;
ctl->timebase_cb_cbset = TRUE;
}
return rc;
}


Loading…
Cancel
Save