Browse Source

use POSIX shm_open instead of sysv shm API

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@353 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 22 years ago
parent
commit
998de8cc9a
13 changed files with 181 additions and 174 deletions
  1. +9
    -3
      configure.in
  2. +12
    -12
      example-clients/Makefile.am
  3. +4
    -0
      example-clients/simple_client.c
  4. +1
    -1
      jack.pc.in
  5. +5
    -3
      jack/engine.h
  6. +19
    -11
      jack/internal.h
  7. +2
    -0
      jack/jack.h
  8. +1
    -1
      jack/port.h
  9. +2
    -0
      jack/types.h
  10. +1
    -1
      jackd/Makefile.am
  11. +79
    -102
      jackd/engine.c
  12. +43
    -38
      libjack/client.c
  13. +3
    -2
      libjack/port.c

+ 9
- 3
configure.in View File

@@ -13,7 +13,7 @@ dnl micro version = incremented when implementation-only
dnl changes are made
dnl ---
JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=63
JACK_MINOR_VERSION=64
JACK_MICRO_VERSION=0

dnl ---
@@ -24,7 +24,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=3
JACK_PROTOCOL_VERSION=4

dnl ---
dnl HOWTO: updating the libjack interface version
@@ -41,7 +41,7 @@ dnl slacker than this, and closer to those for the JACK version
dnl number.
dnl ---
JACK_API_CURRENT=0
JACK_API_REVISION=11
JACK_API_REVISION=12
JACK_API_AGE=0

AC_SUBST(JACK_MAJOR_VERSION)
@@ -95,6 +95,12 @@ AC_ARG_ENABLE(optimize,

AC_SUBST(JACK_CFLAGS)

dnl
dnl use JACK_CFLAGS for jackd compilation
dnl

CFLAGS=$JACK_CFLAGS

AC_ARG_ENABLE(debug,
[ --enable-debug enable debugging messages in jackd and libjack],
[ if test "x$enable_debug" != "xno" ; then


+ 12
- 12
example-clients/Makefile.am View File

@@ -45,48 +45,48 @@ AM_CFLAGS = -I.. $(JACK_CFLAGS) $(sndfile_cflags)
AM_CXXFLAGS = -I.. $(JACK_CFLAGS) $(sndfile_cflags)

jack_simple_client_SOURCES = simple_client.c
jack_simple_client_LDFLAGS = -ldl -lpthread
jack_simple_client_LDFLAGS = -lrt -ldl -lpthread
jack_simple_client_LDADD = ../libjack/libjack.la

jack_connect_SOURCES = connect.c
jack_connect_LDFLAGS = -ldl -lpthread
jack_connect_LDFLAGS = -lrt -ldl -lpthread
jack_connect_LDADD = ../libjack/libjack.la

jack_disconnect_SOURCES = connect.c
jack_disconnect_LDFLAGS = -ldl -lpthread
jack_disconnect_LDFLAGS = -lrt -ldl -lpthread
jack_disconnect_LDADD = ../libjack/libjack.la

jack_monitor_client_SOURCES = monitor_client.c
jack_monitor_client_LDFLAGS = -ldl -lpthread
jack_monitor_client_LDFLAGS = -lrt -ldl -lpthread
jack_monitor_client_LDADD = ../libjack/libjack.la

jack_metro_SOURCES = metro.c
jack_metro_LDFLAGS = -ldl -lpthread
jack_metro_LDFLAGS = -lrt -ldl -lpthread
jack_metro_LDADD = ../libjack/libjack.la

jack_lsp_SOURCES = lsp.c
jack_lsp_LDFLAGS = -ldl -lpthread
jack_lsp_LDFLAGS = -lrt -ldl -lpthread
jack_lsp_LDADD = ../libjack/libjack.la

jack_showtime_SOURCES = showtime.c
jack_showtime_LDFLAGS = -ldl -lpthread
jack_showtime_LDFLAGS = -lrt -ldl -lpthread
jack_showtime_LDADD = ../libjack/libjack.la


if HAVE_FLTK
jack_fltk_client_SOURCES = fltk_client.cc
jack_fltk_client_LDFLAGS = -L/usr/X11R6/lib -lfltk -lX11 -lXext -ldl -lpthread
jack_fltk_client_LDFLAGS = -L/usr/X11R6/lib -lfltk -lX11 -lXext -lrt -ldl -lpthread
jack_fltk_client_LDADD = ../libjack/libjack.la
endif

if HAVE_SNDFILE
jackrec_SOURCES = capture_client.c
jackrec_LDFLAGS = @SNDFILE_LIBS@ -ldl -lpthread
jackrec_LDFLAGS = @SNDFILE_LIBS@ -lrt -ldl -lpthread
jackrec_LDADD = ../libjack/libjack.la
endif

jack_impulse_grabber_SOURCES = impulse_grabber.c
jack_impulse_grabber_LDFLAGS = -ldl -lpthread -lm
jack_impulse_grabber_LDFLAGS = -lrt -ldl -lpthread -lm
jack_impulse_grabber_LDADD = ../libjack/libjack.la

#
@@ -94,11 +94,11 @@ jack_impulse_grabber_LDADD = ../libjack/libjack.la
#

jack_load_SOURCES = ipload.c
jack_load_LDFLAGS = -ldl -lpthread -lm
jack_load_LDFLAGS = -lrt -ldl -lpthread -lm
jack_load_LDADD = ../libjack/libjack.la

jack_unload_SOURCES = ipunload.c
jack_unload_LDFLAGS = -ldl -lpthread -lm
jack_unload_LDFLAGS = -lrt -ldl -lpthread -lm
jack_unload_LDADD = ../libjack/libjack.la

#


+ 4
- 0
example-clients/simple_client.c View File

@@ -98,7 +98,9 @@ main (int argc, char *argv[])
/* create two ports */

input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fprintf (stderr, "got ip\n");
output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fprintf (stderr, "got op\n");

/* tell the JACK server that we are ready to roll */

@@ -107,6 +109,8 @@ main (int argc, char *argv[])
return 1;
}

fprintf (stderr, "activated\n");

/* connect the ports. Note: you can't do this before
the client is activated, because we can't allow
connections to be made to clients that aren't


+ 1
- 1
jack.pc.in View File

@@ -6,5 +6,5 @@ includedir=@includedir@
Name: jack
Description: the Jack Audio Connection Kit: a low-latency synchronous callback-based media server
Version: @JACK_VERSION@
Libs: -L${libdir} -ljack -lpthread -ldl
Libs: -L${libdir} -ljack -lpthread -ldl -lrt
Cflags: -I${includedir}

+ 5
- 3
jack/engine.h View File

@@ -50,9 +50,11 @@ struct _jack_engine {
int process_errors;
int period_msecs;
unsigned int port_max;
int control_shm_id;
key_t control_key;
key_t port_segment_key; /* XXX fix me */
int control_shm_fd;
shm_name_t control_shm_name;
size_t control_size;
shm_name_t port_segment_name; /* XXX fix me */
size_t port_segment_size; /* XXX fix me */
void *port_segment_address; /* XXX fix me */
pthread_t main_thread;
pthread_t server_thread;


+ 19
- 11
jack/internal.h View File

@@ -56,13 +56,14 @@ typedef struct _jack_request jack_request_t;
typedef void * dlhandle;

typedef struct {
int shm_key;
shm_name_t shm_name;
size_t offset;
} jack_port_buffer_info_t;

typedef struct {
int shm_key;
char *address;
shm_name_t shm_name;
char *address;
size_t size;
} jack_port_segment_info_t;

typedef struct _time_info
@@ -136,13 +137,16 @@ typedef struct {
unsigned long n;
jack_port_id_t port_id;
jack_port_id_t self_id;
int key;
shm_name_t shm_name;
} x;
union {
unsigned long n;
jack_port_id_t other_id;
void* addr;
} y;
union {
size_t size;
} z;
} jack_event_t;

typedef enum {
@@ -216,10 +220,10 @@ typedef struct {

int status;

unsigned int protocol_v;
unsigned int protocol_v;

int client_key;
int control_key;
shm_name_t client_shm_name;
shm_name_t control_shm_name;

char fifo_prefix[PATH_MAX+1];

@@ -231,11 +235,13 @@ typedef struct {
*/

jack_client_control_t *client_control;
jack_control_t *engine_control;
jack_control_t *engine_control;
size_t control_size;

/* XXX need to be able to use more than one port segment key */
/* XXX need to be able to use more than one port segment */

key_t port_segment_key;
shm_name_t port_segment_name;
size_t port_segment_size;

} jack_client_connect_result_t;

@@ -291,7 +297,7 @@ extern void jack_cleanup_shm ();
extern void jack_cleanup_files ();

extern int jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event);
extern void jack_client_handle_new_port_segment (jack_client_t *client, int key, void* addr);
extern void jack_client_handle_new_port_segment (jack_client_t *client, shm_name_t, size_t, void* addr);

extern jack_client_t *jack_driver_client_new (jack_engine_t *, const char *client_name);
jack_client_t *jack_client_alloc_internal (jack_client_control_t*, jack_control_t*);
@@ -304,6 +310,8 @@ extern char *jack_server_dir;

extern void jack_error (const char *fmt, ...);

extern char *jack_get_shm (const char *shm_name, size_t size, int perm, int mode, int prot);

#endif /* __jack_internal_h__ */




+ 2
- 0
jack/jack.h View File

@@ -202,6 +202,8 @@ int jack_port_unregister (jack_client_t *, jack_port_t *);
* zero-filled. if there are multiple inbound connections, the data
* will be mixed appropriately.
*
* FOR OUTPUT PORTS ONLY
* ---------------------
* You may cache the value returned, but only between calls to
* your "blocksize" callback. For this reason alone, you should
* either never cache the return value or ensure you have


+ 1
- 1
jack/port.h View File

@@ -72,7 +72,7 @@ typedef struct _jack_port_type_info {
*/

typedef struct _jack_port_shared {
int shm_key;
shm_name_t shm_name;
size_t offset;
unsigned long flags;


+ 2
- 0
jack/types.h View File

@@ -23,6 +23,8 @@

#include <limits.h> /* ULONG_MAX */

typedef char shm_name_t[64];

/**
* Type used to represent sample frame counts.
*/


+ 1
- 1
jackd/Makefile.am View File

@@ -24,7 +24,7 @@ bin_PROGRAMS = jackd $(CAP_PROGS)
AM_CFLAGS = $(JACK_CFLAGS) -DJACKD_LOCATION=\"$(bindir)/jackd\"

jackd_SOURCES = jackd.c engine.c
jackd_LDADD = ../libjack/libjack.la -lm -ldl -lpthread $(CAP_LIBS)
jackd_LDADD = ../libjack/libjack.la -lm -ldl -lrt -lpthread $(CAP_LIBS)

noinst_HEADERS = jack_md5.h md5.h md5_loc.h



+ 79
- 102
jackd/engine.c View File

@@ -23,11 +23,10 @@
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/un.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdarg.h>
#include <dirent.h>
@@ -36,7 +35,6 @@
#include <sys/types.h>
#include <string.h>
#include <limits.h>
#include <sys/mman.h>

#include <config.h>

@@ -73,20 +71,20 @@ typedef struct _jack_client_internal {

jack_client_control_t *control;

int request_fd;
int event_fd;
int subgraph_start_fd;
int subgraph_wait_fd;
JSList *ports; /* protected by engine->client_lock */
JSList *fed_by; /* protected by engine->client_lock */
int shm_id;
int shm_key;
unsigned long execution_order;
struct _jack_client_internal *next_client; /* not a linked list! */
dlhandle handle;
int (*initialize)(jack_client_t*, const char*); /* for internal clients only */
void (*finish)(void); /* for internal clients only */
int error;
int request_fd;
int event_fd;
int subgraph_start_fd;
int subgraph_wait_fd;
JSList *ports; /* protected by engine->client_lock */
JSList *fed_by; /* protected by engine->client_lock */
int shm_fd;
shm_name_t shm_name;
unsigned long execution_order;
struct _jack_client_internal *next_client; /* not a linked list! */
dlhandle handle;
int (*initialize)(jack_client_t*, const char*); /* for internal clients only */
void (*finish)(void); /* for internal clients only */
int error;

} jack_client_internal_t;

@@ -137,8 +135,8 @@ static int internal_client_request (void*, jack_request_t *);

static int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver);

static int *jack_shm_registry;
static int jack_shm_id_cnt;
static shm_name_t *jack_shm_registry;
static int jack_shm_id_cnt;

static char *client_state_names[] = {
"Not triggered",
@@ -261,7 +259,6 @@ make_sockets (int fd[2])
static int
jack_initialize_shm ()
{
int shmid_id;
void *addr;

if (jack_shm_registry != NULL) {
@@ -274,31 +271,24 @@ jack_initialize_shm ()
or debugger driven exits.
*/
if ((shmid_id = shmget (random(), sizeof(int) * MAX_SHM_ID, IPC_CREAT|0600)) < 0) {
jack_error ("cannot create engine shm ID registry (%s)", strerror (errno));
return -1;
}
if ((addr = shmat (shmid_id, 0, 0)) == (void *) -1) {
jack_error ("cannot attach shm ID registry (%s)", strerror (errno));
shmctl (shmid_id, IPC_RMID, 0);
return -1;
}
if (shmctl (shmid_id, IPC_RMID, NULL)) {
jack_error ("cannot mark shm ID registry as destroyed (%s)", strerror (errno));
if ((addr = jack_get_shm ("/jack-shm-registry", sizeof (shm_name_t) * MAX_SHM_ID,
O_RDWR|O_CREAT|O_TRUNC, 0600, PROT_READ|PROT_WRITE)) == MAP_FAILED) {
return -1;
}

jack_shm_registry = (int *) addr;
jack_shm_registry = (shm_name_t *) addr;
jack_shm_id_cnt = 0;

sprintf (jack_shm_registry[0], "hello");

return 0;
}

static void
jack_register_shm (int shmid)
jack_register_shm (char *shm_name)
{
if (jack_shm_id_cnt < MAX_SHM_ID) {
jack_shm_registry[jack_shm_id_cnt++] = shmid;
snprintf (jack_shm_registry[jack_shm_id_cnt++], sizeof (shm_name_t), shm_name);
}
}

@@ -308,7 +298,7 @@ jack_cleanup_shm ()
int i;

for (i = 0; i < jack_shm_id_cnt; i++) {
shmctl (jack_shm_registry[i], IPC_RMID, NULL);
shm_unlink (jack_shm_registry[i]);
}
}

@@ -344,36 +334,35 @@ jack_add_port_segment (jack_engine_t *engine, unsigned long nports)
{
jack_event_t event;
jack_port_segment_info_t *si;
key_t key;
int id;
char *addr;
size_t offset;
size_t size;
size_t step;
shm_name_t shm_name;

key = random();
snprintf (shm_name, sizeof(shm_name), "/jack-port-segment-%d", jack_slist_length (engine->port_segments));
size = nports * sizeof (jack_default_audio_sample_t) * engine->control->buffer_size;

if ((id = shmget (key, size, IPC_CREAT|0666)) < 0) {
jack_error ("cannot create new port segment of %d bytes, key = 0x%x (%s)", size, key, strerror (errno));
if ((addr = jack_get_shm (shm_name, size, (O_RDWR|O_CREAT|O_TRUNC), 0666, PROT_READ|PROT_WRITE)) == MAP_FAILED) {
jack_error ("cannot create new port segment of %d bytes, shm_name = %s (%s)", size, shm_name, strerror (errno));
return -1;
}
jack_register_shm (id);

if ((addr = shmat (id, 0, 0)) == (char *) -1) {
jack_error ("cannot attach new port segment (%s)", strerror (errno));
shmctl (id, IPC_RMID, 0);
return -1;
}
jack_register_shm (shm_name);
si = (jack_port_segment_info_t *) malloc (sizeof (jack_port_segment_info_t));
si->shm_key = key;
strcpy (si->shm_name, shm_name);
si->address = addr;

engine->port_segments = jack_slist_prepend (engine->port_segments, si);
engine->port_segment_key = key; /* XXX fix me */
engine->port_segment_address = addr; /* XXX fix me */
/* XXXX this needs fixing so that we can support multiple port segments.
or does it?
*/

strcpy (engine->port_segment_name, shm_name);
engine->port_segment_address = addr;
engine->port_segment_size = size;

pthread_mutex_lock (&engine->buffer_lock);

@@ -385,7 +374,7 @@ jack_add_port_segment (jack_engine_t *engine, unsigned long nports)
jack_port_buffer_info_t *bi;

bi = (jack_port_buffer_info_t *) malloc (sizeof (jack_port_buffer_info_t));
bi->shm_key = key;
strcpy (bi->shm_name, si->shm_name);
bi->offset = offset;

/* we append because we want the list to be in memory-address order */
@@ -411,7 +400,7 @@ jack_add_port_segment (jack_engine_t *engine, unsigned long nports)
/* tell everybody about it */

event.type = NewPortBufferSegment;
event.x.key = key;
strcpy (event.x.shm_name, shm_name);
event.y.addr = addr;

jack_deliver_event_to_all (engine, &event);
@@ -789,9 +778,11 @@ setup_client (jack_engine_t *engine, int client_fd, jack_client_connect_request_
}
res->protocol_v = jack_protocol_version;
res->client_key = client->shm_key;
res->control_key = engine->control_key;
res->port_segment_key = engine->port_segment_key;
strcpy (res->client_shm_name, client->shm_name);
strcpy (res->control_shm_name, engine->control_shm_name);
strcpy (res->port_segment_name, engine->port_segment_name);
res->port_segment_size = engine->port_segment_size;
res->control_size = engine->control_size;
res->realtime = engine->control->real_time;
res->realtime_priority = engine->rtpriority - 1;
@@ -808,7 +799,7 @@ setup_client (jack_engine_t *engine, int client_fd, jack_client_connect_request_
res->client_control = client->control;
res->engine_control = engine->control;
} else {
strcpy (res->fifo_prefix, engine->fifo_prefix);
}
@@ -839,7 +830,8 @@ setup_client (jack_engine_t *engine, int client_fd, jack_client_connect_request_
/* tell it about the port segment. XXX fix to work with multiples */

jack_client_handle_new_port_segment (client->control->private_client,
engine->port_segment_key,
engine->port_segment_name,
engine->port_segment_size,
engine->port_segment_address);

if (client->initialize (client->control->private_client, req->object_data)) {
@@ -982,7 +974,6 @@ handle_unload_client (jack_engine_t *engine, int client_fd, jack_client_connect_
for (node = engine->clients; node; node = jack_slist_next (node)) {
if (strcmp ((char *) ((jack_client_internal_t *) node->data)->control->name, req->name) == 0) {
jack_remove_client (engine, (jack_client_internal_t *) node->data);
fprintf (stderr, "found it\n");
res.status = 0;
break;
}
@@ -1191,7 +1182,7 @@ jack_client_activate (jack_engine_t *engine, jack_client_id_t id)
jack_client_internal_t *client;
JSList *node;
int ret = -1;
jack_lock_graph (engine);

for (node = engine->clients; node; node = jack_slist_next (node)) {
@@ -1581,7 +1572,6 @@ jack_engine_t *
jack_engine_new (int realtime, int rtpriority, int verbose)
{
jack_engine_t *engine;
size_t control_size;
void *addr;
unsigned int i;
#ifdef USE_CAPABILITIES
@@ -1633,26 +1623,21 @@ jack_engine_new (int realtime, int rtpriority, int verbose)

srandom (time ((time_t *) 0));

engine->control_key = random();
control_size = sizeof (jack_control_t) + (sizeof (jack_port_shared_t) * engine->port_max);
snprintf (engine->control_shm_name, sizeof (engine->control_shm_name), "/jack-engine");
engine->control_size = sizeof (jack_control_t) + (sizeof (jack_port_shared_t) * engine->port_max);

if (jack_initialize_shm (engine)) {
return 0;
}

if ((engine->control_shm_id = shmget (engine->control_key, control_size, IPC_CREAT|0644)) < 0) {
if ((addr = jack_get_shm (engine->control_shm_name, engine->control_size,
O_RDWR|O_CREAT|O_TRUNC, 0644, PROT_READ|PROT_WRITE)) == MAP_FAILED) {
jack_error ("cannot create engine control shared memory segment (%s)", strerror (errno));
return 0;
}

jack_register_shm (engine->control_shm_id);
jack_register_shm (engine->control_shm_name);
if ((addr = shmat (engine->control_shm_id, 0, 0)) == (void *) -1) {
jack_error ("cannot attach control shared memory segment (%s)", strerror (errno));
shmctl (engine->control_shm_id, IPC_RMID, 0);
return 0;
}

engine->control = (jack_control_t *) addr;
engine->control->engine = engine;

@@ -2041,8 +2026,10 @@ jack_engine_delete (jack_engine_t *engine)

{
if (engine) {
close (engine->control_shm_fd);
return pthread_cancel (engine->main_thread);
}

return 0;
}

@@ -2051,8 +2038,8 @@ jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_req

{
jack_client_internal_t *client;
key_t shm_key = 0;
int shm_id = 0;
shm_name_t shm_name;
int shm_fd = 0;
void *addr = 0;

switch (req->type) {
@@ -2062,21 +2049,13 @@ jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_req

case ClientExternal:

shm_key = random();
if ((shm_id = shmget (shm_key, sizeof (jack_client_control_t), IPC_CREAT|0666)) < 0) {
jack_error ("cannot create client control block");
snprintf (shm_name, sizeof (shm_name), "/jack-c-%s", req->name);
if ((addr = jack_get_shm (shm_name, sizeof (jack_client_control_t),
(O_RDWR|O_CREAT|O_TRUNC), 0666, PROT_READ|PROT_WRITE)) == MAP_FAILED) {
jack_error ("cannot create client control block for %s", req->name);
return 0;
}
jack_register_shm (shm_id);

if ((addr = shmat (shm_id, 0, 0)) == (void *) -1) {
jack_error ("cannot attach new client control block");
shmctl (shm_id, IPC_RMID, 0);
return 0;
}

jack_register_shm (shm_name);
break;
}

@@ -2098,8 +2077,8 @@ jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_req

} else {

client->shm_id = shm_id;
client->shm_key = shm_key;
client->shm_fd = shm_fd;
strcpy (client->shm_name, shm_name);
client->control = (jack_client_control_t *) addr;
}

@@ -2236,8 +2215,9 @@ jack_client_delete (jack_engine_t *engine, jack_client_internal_t *client)
jack_client_unload (client);
free ((char *) client->control);
} else {
shmdt ((void *) client->control);
shmctl(client->shm_id,IPC_RMID,0);
munmap ((void*) client->control, sizeof (*client->control));
shm_unlink (client->shm_name);
close (client->shm_fd);
}

free (client);
@@ -2309,8 +2289,6 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_

if (jack_client_is_internal (client)) {

fprintf (stderr, "delivering event %d to IP client %s\n", event->type, client->control->name);

switch (event->type) {
case PortConnected:
case PortDisconnected:
@@ -2342,7 +2320,8 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_
break;

case NewPortBufferSegment:
jack_client_handle_new_port_segment (client->control->private_client, event->x.key, event->y.addr);
jack_client_handle_new_port_segment (client->control->private_client,
event->x.shm_name, event->z.size, event->y.addr);
break;

default:
@@ -2841,8 +2820,6 @@ jack_port_do_connect (jack_engine_t *engine,
jack_port_internal_t *srcport, *dstport;
jack_port_id_t src_id, dst_id;

fprintf (stderr, "got connect request\n");

if ((srcport = jack_get_port_by_name (engine, source_port)) == NULL) {
jack_error ("unknown source port in attempted connection [%s]", source_port);
return -1;
@@ -3392,7 +3369,7 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
jack_port_segment_info_t *psi = 0;
jack_port_buffer_info_t *bi;

port->shared->shm_key = -1;
port->shared->shm_name[0] = '\0';

if (port->shared->flags & JackPortIsInput) {
port->shared->offset = 0;
@@ -3413,8 +3390,8 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)

psi = (jack_port_segment_info_t *) node->data;

if (bi->shm_key == psi->shm_key) {
port->shared->shm_key = psi->shm_key;
if (strcmp (bi->shm_name, psi->shm_name) == 0) {
strcpy (port->shared->shm_name, psi->shm_name);
port->shared->offset = bi->offset;
port->buffer_info = bi;
break;
@@ -3422,23 +3399,23 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
}

if (engine->verbose) {
fprintf (stderr, "port %s buf shm key 0x%x at offset %d bi = %p\n",
fprintf (stderr, "port %s buf shm name %s at offset %d bi = %p\n",
port->shared->name,
port->shared->shm_key,
port->shared->shm_name,
(int)port->shared->offset,
port->buffer_info);
}

if (port->shared->shm_key >= 0) {
if (port->shared->shm_name[0] != '\0') {
engine->port_buffer_freelist = jack_slist_remove (engine->port_buffer_freelist, bi);
} else {
jack_error ("port segment info for 0x%x:%d not found!", bi->shm_key, bi->offset);
jack_error ("port segment info for %s:%d not found!", bi->shm_name, bi->offset);
}

pthread_mutex_unlock (&engine->buffer_lock);

if (port->shared->shm_key < 0) {
if (port->shared->shm_name[0] == '\0') {
return -1;
} else {
return 0;


+ 43
- 38
libjack/client.c View File

@@ -25,7 +25,6 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <stdarg.h>
@@ -74,6 +73,32 @@ typedef struct {
const char *client_name;
} client_info;

char *
jack_get_shm (const char *shm_name, size_t size, int perm, int mode, int prot)
{
int shm_fd;
char *addr;

if ((shm_fd = shm_open (shm_name, perm, mode)) < 0) {
jack_error ("cannot create shm segment %s (%s)", shm_name, strerror (errno));
return MAP_FAILED;
}

if (ftruncate (shm_fd, size) < 0) {
jack_error ("cannot set size of engine shm registry (%s)", strerror (errno));
return MAP_FAILED;
}

if ((addr = mmap (0, size, prot, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) {
jack_error ("cannot mmap shm segment %s (%s)", shm_name, strerror (errno));
shm_unlink (shm_name);
close (shm_fd);
return MAP_FAILED;
}

return addr;
}

void
jack_error (const char *fmt, ...)
{
@@ -446,8 +471,6 @@ jack_client_new (const char *client_name)
int ev_fd = -1;
jack_client_connect_result_t res;
jack_client_t *client;
int client_shm_id;
int control_shm_id;
void *addr;

/* external clients need this initialized; internal clients
@@ -470,12 +493,8 @@ jack_client_new (const char *client_name)

/* attach the engine control/info block */

if ((control_shm_id = shmget (res.control_key, 0, 0)) < 0) {
jack_error ("cannot determine shared memory segment for control key 0x%x", res.control_key);
goto fail;
}

if ((addr = shmat (control_shm_id, 0, 0)) == (void *) -1) {
if ((addr = jack_get_shm (res.control_shm_name, res.control_size, O_RDWR,
0, (PROT_READ|PROT_WRITE))) == MAP_FAILED) {
jack_error ("cannot attached engine control shared memory segment");
goto fail;
}
@@ -484,19 +503,15 @@ jack_client_new (const char *client_name)

/* now attach the client control block */

if ((client_shm_id = shmget (res.client_key, 0, 0)) < 0) {
jack_error ("cannot determine shared memory segment for client key 0x%x", res.client_key);
goto fail;
}

if ((addr = shmat (client_shm_id, 0, 0)) == (void *) -1) {
if ((addr = jack_get_shm (res.client_shm_name, sizeof (jack_client_control_t), O_RDWR,
0, (PROT_READ|PROT_WRITE))) == MAP_FAILED) {
jack_error ("cannot attached client control shared memory segment");
goto fail;
}

client->control = (jack_client_control_t *) addr;

jack_client_handle_new_port_segment (client, res.port_segment_key, 0);
jack_client_handle_new_port_segment (client, res.port_segment_name, res.port_segment_size, 0);

/* set up the client so that it does the right thing for an external client */

@@ -514,10 +529,10 @@ jack_client_new (const char *client_name)
fail:
if (client->engine) {
shmdt (client->engine);
munmap ((char *) client->engine, sizeof (jack_control_t));
}
if (client->control) {
shmdt ((char *) client->control);
munmap ((char *) client->control, sizeof (jack_client_control_t));
}
if (req_fd >= 0) {
close (req_fd);
@@ -563,10 +578,9 @@ jack_internal_client_close (const char *client_name)
}

void
jack_client_handle_new_port_segment (jack_client_t *client, int key, void* addr)
jack_client_handle_new_port_segment (jack_client_t *client, shm_name_t shm_name, size_t size, void* addr)
{
jack_port_segment_info_t *si;
int port_segment_shm_id;

/* Lookup, attach and register the port/buffer segments in use
right now.
@@ -574,15 +588,8 @@ jack_client_handle_new_port_segment (jack_client_t *client, int key, void* addr)

if (client->control->type == ClientExternal) {

/* map shared memory */

if ((port_segment_shm_id = shmget (key, 0, 0)) < 0) {
jack_error ("cannot determine shared memory segment for port segment key 0x%x (%s)",
key, strerror (errno));
return;
}
if ((addr = shmat (port_segment_shm_id, 0, 0)) == (void *) -1) {
if ((addr = jack_get_shm(shm_name, size, O_RDWR, 0, (PROT_READ|PROT_WRITE))) == MAP_FAILED) {
jack_error ("cannot attached port segment shared memory (%s)", strerror (errno));
return;
}
@@ -593,8 +600,9 @@ jack_client_handle_new_port_segment (jack_client_t *client, int key, void* addr)
}

si = (jack_port_segment_info_t *) malloc (sizeof (jack_port_segment_info_t));
si->shm_key = key;
strcpy (si->shm_name, shm_name);
si->address = addr;
si->size = size;

/* the first chunk of the first port segment is always set by the engine
to be a conveniently-sized, zero-filled lump of memory.
@@ -626,10 +634,6 @@ jack_client_thread (void *arg)
pthread_cond_signal (&client_ready);
pthread_mutex_unlock (&client_lock);

/* XXX reset the PID to be the actual client thread. Kai and Fernando know
about this and it needs fixing.
*/

client->control->pid = getpid();

DEBUG ("client thread is now running");
@@ -725,7 +729,7 @@ jack_client_thread (void *arg)
break;

case NewPortBufferSegment:
jack_client_handle_new_port_segment (client, event.x.key, event.y.addr);
jack_client_handle_new_port_segment (client, event.x.shm_name, event.z.size, event.y.addr);
break;
}

@@ -1044,7 +1048,7 @@ jack_activate (jack_client_t *client)
pthread_mutex_unlock (&client_lock);
return -1;
}
pthread_cond_wait (&client_ready, &client_lock);
pthread_mutex_unlock (&client_lock);
@@ -1091,11 +1095,12 @@ jack_client_close (jack_client_t *client)
pthread_cancel (client->thread);
pthread_join (client->thread, &status);

shmdt ((char *) client->control);
shmdt (client->engine);
munmap ((char *) client->control, sizeof (jack_client_control_t));
munmap ((char *) client->engine, sizeof (jack_control_t));

for (node = client->port_segments; node; node = jack_slist_next (node)) {
shmdt (((jack_port_segment_info_t *) node->data)->address);
jack_port_segment_info_t *si = (jack_port_segment_info_t *) node->data;
munmap ((char *) si->address, si->size);
free (node->data);
}
jack_slist_free (client->port_segments);


+ 3
- 2
libjack/port.c View File

@@ -60,8 +60,9 @@ jack_port_new (const jack_client_t *client, jack_port_id_t port_id, jack_control
for (node = client->port_segments; node; node = jack_slist_next (node)) {
si = (jack_port_segment_info_t *) node->data;
if (si->shm_key == port->shared->shm_key) {

if (strcmp (si->shm_name, port->shared->shm_name) == 0) {
fprintf (stderr, "found port segment for %s\n", port->shared->name);
break;
}
}


Loading…
Cancel
Save