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 changes are made
dnl --- dnl ---
JACK_MAJOR_VERSION=0 JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=63
JACK_MINOR_VERSION=64
JACK_MICRO_VERSION=0 JACK_MICRO_VERSION=0


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


dnl --- dnl ---
dnl HOWTO: updating the libjack interface version 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 number.
dnl --- dnl ---
JACK_API_CURRENT=0 JACK_API_CURRENT=0
JACK_API_REVISION=11
JACK_API_REVISION=12
JACK_API_AGE=0 JACK_API_AGE=0


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


AC_SUBST(JACK_CFLAGS) AC_SUBST(JACK_CFLAGS)


dnl
dnl use JACK_CFLAGS for jackd compilation
dnl

CFLAGS=$JACK_CFLAGS

AC_ARG_ENABLE(debug, AC_ARG_ENABLE(debug,
[ --enable-debug enable debugging messages in jackd and libjack], [ --enable-debug enable debugging messages in jackd and libjack],
[ if test "x$enable_debug" != "xno" ; then [ 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) AM_CXXFLAGS = -I.. $(JACK_CFLAGS) $(sndfile_cflags)


jack_simple_client_SOURCES = simple_client.c 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_simple_client_LDADD = ../libjack/libjack.la


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


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


jack_monitor_client_SOURCES = monitor_client.c 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_monitor_client_LDADD = ../libjack/libjack.la


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


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


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




if HAVE_FLTK if HAVE_FLTK
jack_fltk_client_SOURCES = fltk_client.cc 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 jack_fltk_client_LDADD = ../libjack/libjack.la
endif endif


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


jack_impulse_grabber_SOURCES = impulse_grabber.c 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 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_SOURCES = ipload.c
jack_load_LDFLAGS = -ldl -lpthread -lm
jack_load_LDFLAGS = -lrt -ldl -lpthread -lm
jack_load_LDADD = ../libjack/libjack.la jack_load_LDADD = ../libjack/libjack.la


jack_unload_SOURCES = ipunload.c jack_unload_SOURCES = ipunload.c
jack_unload_LDFLAGS = -ldl -lpthread -lm
jack_unload_LDFLAGS = -lrt -ldl -lpthread -lm
jack_unload_LDADD = ../libjack/libjack.la 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 */ /* create two ports */


input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); 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); 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 */ /* tell the JACK server that we are ready to roll */


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


fprintf (stderr, "activated\n");

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


+ 1
- 1
jack.pc.in View File

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

+ 5
- 3
jack/engine.h View File

@@ -50,9 +50,11 @@ struct _jack_engine {
int process_errors; int process_errors;
int period_msecs; int period_msecs;
unsigned int port_max; 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 */ void *port_segment_address; /* XXX fix me */
pthread_t main_thread; pthread_t main_thread;
pthread_t server_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 void * dlhandle;


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


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


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


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


int status; 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]; char fifo_prefix[PATH_MAX+1];


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


jack_client_control_t *client_control; 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; } jack_client_connect_result_t;


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


extern int jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event); 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); 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*); 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 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__ */ #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 * zero-filled. if there are multiple inbound connections, the data
* will be mixed appropriately. * will be mixed appropriately.
* *
* FOR OUTPUT PORTS ONLY
* ---------------------
* You may cache the value returned, but only between calls to * You may cache the value returned, but only between calls to
* your "blocksize" callback. For this reason alone, you should * your "blocksize" callback. For this reason alone, you should
* either never cache the return value or ensure you have * 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 { typedef struct _jack_port_shared {
int shm_key;
shm_name_t shm_name;
size_t offset; size_t offset;
unsigned long flags; unsigned long flags;


+ 2
- 0
jack/types.h View File

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


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


typedef char shm_name_t[64];

/** /**
* Type used to represent sample frame counts. * 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\" AM_CFLAGS = $(JACK_CFLAGS) -DJACKD_LOCATION=\"$(bindir)/jackd\"


jackd_SOURCES = jackd.c engine.c 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 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/socket.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/shm.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <dirent.h> #include <dirent.h>
@@ -36,7 +35,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <sys/mman.h>


#include <config.h> #include <config.h>


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


jack_client_control_t *control; 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; } 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_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[] = { static char *client_state_names[] = {
"Not triggered", "Not triggered",
@@ -261,7 +259,6 @@ make_sockets (int fd[2])
static int static int
jack_initialize_shm () jack_initialize_shm ()
{ {
int shmid_id;
void *addr; void *addr;


if (jack_shm_registry != NULL) { if (jack_shm_registry != NULL) {
@@ -274,31 +271,24 @@ jack_initialize_shm ()
or debugger driven exits. 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; return -1;
} }


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


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

return 0; return 0;
} }


static void static void
jack_register_shm (int shmid)
jack_register_shm (char *shm_name)
{ {
if (jack_shm_id_cnt < MAX_SHM_ID) { 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; int i;


for (i = 0; i < jack_shm_id_cnt; 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_event_t event;
jack_port_segment_info_t *si; jack_port_segment_info_t *si;
key_t key;
int id;
char *addr; char *addr;
size_t offset; size_t offset;
size_t size; size_t size;
size_t step; 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; 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; 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 = (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->address = addr;


engine->port_segments = jack_slist_prepend (engine->port_segments, si); 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); 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; jack_port_buffer_info_t *bi;


bi = (jack_port_buffer_info_t *) malloc (sizeof (jack_port_buffer_info_t)); 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; bi->offset = offset;


/* we append because we want the list to be in memory-address order */ /* 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 */ /* tell everybody about it */


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


jack_deliver_event_to_all (engine, &event); 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->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 = engine->control->real_time;
res->realtime_priority = engine->rtpriority - 1; 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->client_control = client->control;
res->engine_control = engine->control; res->engine_control = engine->control;
} else { } else {
strcpy (res->fifo_prefix, engine->fifo_prefix); 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 */ /* tell it about the port segment. XXX fix to work with multiples */


jack_client_handle_new_port_segment (client->control->private_client, 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); engine->port_segment_address);


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


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


srandom (time ((time_t *) 0)); 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)) { if (jack_initialize_shm (engine)) {
return 0; 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)); jack_error ("cannot create engine control shared memory segment (%s)", strerror (errno));
return 0; 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 = (jack_control_t *) addr;
engine->control->engine = engine; engine->control->engine = engine;


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


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

return 0; 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; 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; void *addr = 0;


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


case ClientExternal: 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; 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; break;
} }


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


} else { } 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; 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); jack_client_unload (client);
free ((char *) client->control); free ((char *) client->control);
} else { } 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); 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)) { if (jack_client_is_internal (client)) {


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

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


case NewPortBufferSegment: 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; break;


default: default:
@@ -2841,8 +2820,6 @@ jack_port_do_connect (jack_engine_t *engine,
jack_port_internal_t *srcport, *dstport; jack_port_internal_t *srcport, *dstport;
jack_port_id_t src_id, dst_id; 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) { if ((srcport = jack_get_port_by_name (engine, source_port)) == NULL) {
jack_error ("unknown source port in attempted connection [%s]", source_port); jack_error ("unknown source port in attempted connection [%s]", source_port);
return -1; 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_segment_info_t *psi = 0;
jack_port_buffer_info_t *bi; jack_port_buffer_info_t *bi;


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


if (port->shared->flags & JackPortIsInput) { if (port->shared->flags & JackPortIsInput) {
port->shared->offset = 0; 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; 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->shared->offset = bi->offset;
port->buffer_info = bi; port->buffer_info = bi;
break; break;
@@ -3422,23 +3399,23 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
} }


if (engine->verbose) { 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->name,
port->shared->shm_key,
port->shared->shm_name,
(int)port->shared->offset, (int)port->shared->offset,
port->buffer_info); 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); engine->port_buffer_freelist = jack_slist_remove (engine->port_buffer_freelist, bi);
} else { } 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); pthread_mutex_unlock (&engine->buffer_lock);


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


+ 43
- 38
libjack/client.c View File

@@ -25,7 +25,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <stdarg.h> #include <stdarg.h>
@@ -74,6 +73,32 @@ typedef struct {
const char *client_name; const char *client_name;
} client_info; } 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 void
jack_error (const char *fmt, ...) jack_error (const char *fmt, ...)
{ {
@@ -446,8 +471,6 @@ jack_client_new (const char *client_name)
int ev_fd = -1; int ev_fd = -1;
jack_client_connect_result_t res; jack_client_connect_result_t res;
jack_client_t *client; jack_client_t *client;
int client_shm_id;
int control_shm_id;
void *addr; void *addr;


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


/* attach the engine control/info block */ /* 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"); jack_error ("cannot attached engine control shared memory segment");
goto fail; goto fail;
} }
@@ -484,19 +503,15 @@ jack_client_new (const char *client_name)


/* now attach the client control block */ /* 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"); jack_error ("cannot attached client control shared memory segment");
goto fail; goto fail;
} }


client->control = (jack_client_control_t *) addr; 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 */ /* 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: fail:
if (client->engine) { if (client->engine) {
shmdt (client->engine);
munmap ((char *) client->engine, sizeof (jack_control_t));
} }
if (client->control) { if (client->control) {
shmdt ((char *) client->control);
munmap ((char *) client->control, sizeof (jack_client_control_t));
} }
if (req_fd >= 0) { if (req_fd >= 0) {
close (req_fd); close (req_fd);
@@ -563,10 +578,9 @@ jack_internal_client_close (const char *client_name)
} }


void 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; jack_port_segment_info_t *si;
int port_segment_shm_id;


/* Lookup, attach and register the port/buffer segments in use /* Lookup, attach and register the port/buffer segments in use
right now. 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) { 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)); jack_error ("cannot attached port segment shared memory (%s)", strerror (errno));
return; 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 = (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->address = addr;
si->size = size;


/* the first chunk of the first port segment is always set by the engine /* the first chunk of the first port segment is always set by the engine
to be a conveniently-sized, zero-filled lump of memory. 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_cond_signal (&client_ready);
pthread_mutex_unlock (&client_lock); 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(); client->control->pid = getpid();


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


case NewPortBufferSegment: 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; break;
} }


@@ -1044,7 +1048,7 @@ jack_activate (jack_client_t *client)
pthread_mutex_unlock (&client_lock); pthread_mutex_unlock (&client_lock);
return -1; return -1;
} }
pthread_cond_wait (&client_ready, &client_lock); pthread_cond_wait (&client_ready, &client_lock);
pthread_mutex_unlock (&client_lock); pthread_mutex_unlock (&client_lock);
@@ -1091,11 +1095,12 @@ jack_client_close (jack_client_t *client)
pthread_cancel (client->thread); pthread_cancel (client->thread);
pthread_join (client->thread, &status); 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)) { 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); free (node->data);
} }
jack_slist_free (client->port_segments); 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)) { for (node = client->port_segments; node; node = jack_slist_next (node)) {
si = (jack_port_segment_info_t *) node->data; 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; break;
} }
} }


Loading…
Cancel
Save