Browse Source

update implementation to new async interface

tags/0.120.1
Torben Hohn 15 years ago
parent
commit
79b318cb7a
7 changed files with 179 additions and 64 deletions
  1. +5
    -0
      jack/engine.h
  2. +6
    -2
      jack/internal.h
  3. +1
    -1
      jack/varargs.h
  4. +14
    -12
      jackd/clientengine.c
  5. +104
    -35
      jackd/engine.c
  6. +48
    -14
      libjack/client.c
  7. +1
    -0
      libjack/local.h

+ 5
- 0
jack/engine.h View File

@@ -114,6 +114,11 @@ struct _jack_engine {
char fifo_prefix[PATH_MAX+1];
int *fifo;
unsigned long fifo_size;

/* session handling */
int session_reply_fd;
int session_pending_replies;

unsigned long external_client_cnt;
int rtpriority;
volatile char freewheeling;


+ 6
- 2
jack/internal.h View File

@@ -58,6 +58,7 @@ extern void jack_info (const char *fmt, ...);
#include <jack/types.h>
#include <jack/port.h>
#include <jack/transport.h>
#include <jack/session.h>
#include <jack/thread.h>

extern jack_thread_creator_t jack_thread_creator;
@@ -381,7 +382,8 @@ typedef enum {
SetIdentifier = 27,
GetIdentifier = 28,
RenameClient = 29,
ReserveName = 30
ReserveName = 30,
SessionReply = 31
} RequestType;

struct _jack_request {
@@ -403,7 +405,7 @@ struct _jack_request {
} POST_PACKED_STRUCTURE connect;
struct {
char path[JACK_PORT_NAME_SIZE];
jack_session_event_t type;
jack_session_event_type_t type;
char target[JACK_CLIENT_NAME_SIZE];
} POST_PACKED_STRUCTURE session;
struct {
@@ -481,6 +483,8 @@ typedef struct _jack_client_internal {
int (*initialize)(jack_client_t*, const char*); /* int. clients only */
void (*finish)(void *); /* internal clients only */
int error;

int session_reply_pending;
#ifdef JACK_USE_MACH_THREADS
/* specific resources for server/client real-time thread communication */


+ 1
- 1
jack/varargs.h View File

@@ -54,7 +54,7 @@ jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va)
va->load_name = va_arg(ap, char *);
if ((options & JackLoadInit))
va->load_init = va_arg(ap, char *);
if ((options & JackSessionUUID))
if ((options & JackSessionID))
va->sess_uuid = va_arg(ap, char *);
}



+ 14
- 12
jackd/clientengine.c View File

@@ -406,6 +406,18 @@ jack_client_internal_by_id (jack_engine_t *engine, jack_client_id_t id)
return client;
}

int
jack_client_name_reserved( jack_engine_t *engine, const char *name )
{
JSList *node;
for (node = engine->reserved_client_names; node; node = jack_slist_next (node)) {
jack_reserved_name_t *reservation = (jack_reserved_name_t *) node->data;
if( !strcmp( reservation->name, name ) )
return 1;
}
return 0;
}

/* generate a unique client name
*
* returns 0 if successful, updates name in place
@@ -535,6 +547,8 @@ jack_setup_client_control (jack_engine_t *engine, int fd,
client->subgraph_start_fd = -1;
client->subgraph_wait_fd = -1;

client->session_reply_pending = FALSE;

client->control->process_cbset = FALSE;
client->control->bufsize_cbset = FALSE;
client->control->srate_cbset = FALSE;
@@ -918,18 +932,6 @@ jack_client_deactivate (jack_engine_t *engine, jack_client_id_t id)
return ret;
}

int
jack_client_name_reserved( jack_engine_t *engine, const char *name )
{
JSList *node;
for (node = engine->reserved_client_names; node; node = jack_slist_next (node)) {
jack_reserved_name_t *reservation = (jack_reserved_name_t *) node->data;
if( !strcmp( reservation->name, name ) )
return 1;
}
return 0;
}


int
jack_mark_client_socket_error (jack_engine_t *engine, int fd)


+ 104
- 35
jackd/engine.c View File

@@ -141,6 +141,7 @@ static void jack_do_set_id ( jack_engine_t *engine, jack_request_t *req);
static void jack_do_get_id_by_uuid ( jack_engine_t *engine, jack_request_t *req);
static void jack_do_client_rename ( jack_engine_t *engine, jack_request_t *req);
static void jack_do_reserve_name ( jack_engine_t *engine, jack_request_t *req);
static void jack_do_session_reply (jack_engine_t *engine, jack_request_t *req );


static inline int
@@ -1361,17 +1362,17 @@ do_request (jack_engine_t *engine, jack_request_t *req, int *reply_fd)
break;

case GetClientByUUID:
jack_lock_graph (engine);
jack_rdlock_graph (engine);
jack_do_get_client_by_uuid (engine, req);
jack_unlock_graph (engine);
break;
case GetIdentifier:
jack_lock_graph (engine);
jack_rdlock_graph (engine);
jack_do_get_id_by_uuid( engine, req );
jack_unlock_graph (engine);
break;
case SetIdentifier:
jack_lock_graph (engine);
jack_rdlock_graph (engine);
jack_do_set_id (engine, req);
jack_unlock_graph (engine);
break;
@@ -1381,12 +1382,17 @@ do_request (jack_engine_t *engine, jack_request_t *req, int *reply_fd)
jack_unlock_graph (engine);
break;
case ReserveName:
jack_lock_graph (engine);
jack_rdlock_graph (engine);
jack_do_reserve_name (engine, req);
jack_unlock_graph (engine);
break;
case SessionReply:
jack_rdlock_graph (engine);
jack_do_session_reply (engine, req);
jack_unlock_graph (engine);
break;
case SessionNotify:
jack_lock_graph (engine);
jack_rdlock_graph (engine);
if ((req->status =
jack_do_session_notify (engine, req, *reply_fd))
>= 0) {
@@ -1394,7 +1400,6 @@ do_request (jack_engine_t *engine, jack_request_t *req, int *reply_fd)
*reply_fd = -1;
}
jack_unlock_graph (engine);
req->status = 0;
break;
default:
/* some requests are handled entirely on the client
@@ -1800,6 +1805,9 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int do_unlock,
engine->nozombies = nozombies;
engine->removing_clients = 0;

engine->session_reply_fd = -1;
engine->session_pending_replies = 0;

engine->audio_out_cnt = 0;
engine->audio_in_cnt = 0;
engine->midi_out_cnt = 0;
@@ -2683,6 +2691,33 @@ static void jack_do_reserve_name ( jack_engine_t *engine, jack_request_t *req)
req->status = 0;
}

static int jack_send_session_reply ( jack_engine_t *engine, jack_client_internal_t *client )
{
if (write (engine->session_reply_fd, (const void *) &client->control->uid, sizeof (client->control->uid))
< (ssize_t) sizeof (client->control->uid)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
engine->session_reply_fd, strerror (errno));
return -1;
}
if (write (engine->session_reply_fd, (const void *) client->control->name, sizeof (client->control->name))
< (ssize_t) sizeof (client->control->name)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
engine->session_reply_fd, strerror (errno));
return -1;
}
if (write (engine->session_reply_fd, (const void *) client->control->session_command,
sizeof (client->control->session_command))
< (ssize_t) sizeof (client->control->session_command)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
engine->session_reply_fd, strerror (errno));
return -1;
}

return 0;
}

static int
jack_do_session_notify (jack_engine_t *engine, jack_request_t *req, int reply_fd )
@@ -2690,10 +2725,18 @@ jack_do_session_notify (jack_engine_t *engine, jack_request_t *req, int reply_fd
JSList *node;
jack_event_t event;
int retval = 0;
int reply;
jack_client_id_t finalizer=0;

if (engine->session_reply_fd != -1) {
// we should have a notion of busy or somthing.
// just sending empty reply now.
goto send_final;
}

engine->session_reply_fd = reply_fd;
engine->session_pending_replies = 0;

event.type = SaveSession;
snprintf (event.x.name, sizeof (event.x.name), "%s", req->x.session.path );
event.y.n = req->x.session.type;
@@ -2711,50 +2754,76 @@ jack_do_session_notify (jack_engine_t *engine, jack_request_t *req, int reply_fd

// in case we only want to send to a special client.
// uuid assign is still complete. not sure if thats necessary.
if( (req->x.session.target[0] != 0) && strcmp(req->x.session.target, client->control->name) )
if( (req->x.session.target[0] != 0) && strcmp(req->x.session.target, (char *)client->control->name) )
continue;

reply = jack_deliver_event (engine, client, &event);

if (write (reply_fd, (const void *) &client->control->uid, sizeof (client->control->uid))
< (ssize_t) sizeof (client->control->uid)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
reply_fd, strerror (errno));
goto out;
}
if (write (reply_fd, (const void *) client->control->name, sizeof (client->control->name))
< (ssize_t) sizeof (client->control->name)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
reply_fd, strerror (errno));
goto out;
if (reply == 1) {
// delayed reply
engine->session_pending_replies += 1;
client->session_reply_pending = TRUE;
} else if (reply == 2) {
// immediate reply
if (jack_send_session_reply (engine, client))
goto error_out;
}
if (write (reply_fd, (const void *) client->control->session_command,
sizeof (client->control->session_command))
< (ssize_t) sizeof (client->control->session_command)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
reply_fd, strerror (errno));
goto out;
}

if( reply >= 0 )
retval |= reply;
}
}

if (engine->session_pending_replies != 0)
return 0;

send_final:
if (write (reply_fd, &finalizer, sizeof (finalizer))
< (ssize_t) sizeof (finalizer)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
reply_fd, strerror (errno));
goto out;
goto error_out;
}
return retval;
out:

engine->session_reply_fd = -1;
return 0;
error_out:
return -3;
}

static void jack_do_session_reply (jack_engine_t *engine, jack_request_t *req )
{
jack_client_id_t client_id = req->x.client_id;
jack_client_internal_t *client = jack_client_internal_by_id (engine, client_id);
jack_client_id_t finalizer=0;

req->status = 0;

client->session_reply_pending = FALSE;

if (engine->session_reply_fd == -1) {
jack_error ("spurious Session Reply");
return;
}

engine->session_pending_replies -= 1;

if (jack_send_session_reply (engine, client)) {
// need to fix all client pendings.
client->session_reply_pending =0;
engine->session_reply_fd = -1;
return;
}

if (engine->session_pending_replies == 0) {
if (write (engine->session_reply_fd, &finalizer, sizeof (finalizer))
< (ssize_t) sizeof (finalizer)) {
jack_error ("cannot write SessionNotify result "
"to client via fd = %d (%s)",
engine->session_reply_fd, strerror (errno));
req->status = -1;
}
}
}

static void
jack_notify_all_port_interested_clients (jack_engine_t *engine, jack_client_id_t src, jack_client_id_t dst, jack_port_id_t a, jack_port_id_t b, int connected)
{


+ 48
- 14
libjack/client.c View File

@@ -517,24 +517,28 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)
int
jack_client_handle_session_callback (jack_client_t *client, jack_event_t *event)
{
int retval = 0;
char *cb_ret = NULL;
char prefix[32];
jack_session_event_t *s_event;

if (! client->control->session_cbset) {
return -1;
}

snprintf( prefix, sizeof(prefix), "%d", client->control->uid );

s_event = malloc( sizeof(jack_session_event_t) );
s_event->type = event->y.n;
s_event->session_dir = strdup( event->x.name );
s_event->client_uuid = strdup( prefix );
s_event->command_line = NULL;

if (client->control->session_cbset) {
cb_ret = client->session_cb ( event->y.n, event->x.name, prefix,
client->session_cb_arg);
if(cb_ret) {
retval = 1;
snprintf( (char *)client->control->session_command, sizeof(client->control->session_command),
"%s", cb_ret );
free( cb_ret );
}
}
client->session_cb_immediate_reply = 0;
client->session_cb ( s_event, client->session_cb_arg);

return retval;
if (client->session_cb_immediate_reply) {
return 2;
}
return 1;
}
#if JACK_USE_MACH_THREADS

@@ -1333,10 +1337,40 @@ jack_set_freewheel (jack_client_t* client, int onoff)
return jack_client_deliver_request (client, &request);
}

int
jack_session_reply (jack_client_t *client, jack_session_event_t *event )
{
int retval = 0;

if (event->command_line) {
snprintf ((char *)client->control->session_command,
sizeof(client->control->session_command),
"%s", event->command_line);

free (event->command_line);
} else {
retval = -1;
}

if (pthread_self() == client->thread_id) {
client->session_cb_immediate_reply = 1;
} else {
jack_request_t request;
request.type = SessionReply;
request.x.client_id = client->control->id;

retval = jack_client_deliver_request(client, &request);
}

free ((char *)event->session_dir);
free ((char *)event->client_uuid);
free (event);

return retval;
}

jack_session_command_t *
jack_session_notify (jack_client_t* client, const char *target, jack_session_event_t code, const char *path )
jack_session_notify (jack_client_t* client, const char *target, jack_session_event_type_t code, const char *path )
{
jack_request_t request;



+ 1
- 0
libjack/local.h View File

@@ -35,6 +35,7 @@ struct _jack_client {
char first_active : 1;
pthread_t thread_id;
char name[JACK_CLIENT_NAME_SIZE];
int session_cb_immediate_reply;

#ifdef JACK_USE_MACH_THREADS
/* specific ressources for server/client real-time thread communication */


Loading…
Cancel
Save