diff --git a/configure.in b/configure.in index c62b4b2..62b33cd 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/example-clients/Makefile.am b/example-clients/Makefile.am index 03c86d8..92bca7d 100644 --- a/example-clients/Makefile.am +++ b/example-clients/Makefile.am @@ -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 # diff --git a/example-clients/simple_client.c b/example-clients/simple_client.c index 79a5308..2e51728 100644 --- a/example-clients/simple_client.c +++ b/example-clients/simple_client.c @@ -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 diff --git a/jack.pc.in b/jack.pc.in index 6c77aca..fce463b 100644 --- a/jack.pc.in +++ b/jack.pc.in @@ -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} diff --git a/jack/engine.h b/jack/engine.h index bd1f24f..9d0337f 100644 --- a/jack/engine.h +++ b/jack/engine.h @@ -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; diff --git a/jack/internal.h b/jack/internal.h index b915d08..a5f99cf 100644 --- a/jack/internal.h +++ b/jack/internal.h @@ -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__ */ diff --git a/jack/jack.h b/jack/jack.h index 89d4af2..0db96e0 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -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 diff --git a/jack/port.h b/jack/port.h index 8b37b85..6dfe13e 100644 --- a/jack/port.h +++ b/jack/port.h @@ -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; diff --git a/jack/types.h b/jack/types.h index 898fe17..466fd71 100644 --- a/jack/types.h +++ b/jack/types.h @@ -23,6 +23,8 @@ #include /* ULONG_MAX */ +typedef char shm_name_t[64]; + /** * Type used to represent sample frame counts. */ diff --git a/jackd/Makefile.am b/jackd/Makefile.am index 3b78c75..c13af77 100644 --- a/jackd/Makefile.am +++ b/jackd/Makefile.am @@ -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 diff --git a/jackd/engine.c b/jackd/engine.c index 0c2b3fb..6aa1028 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -23,11 +23,10 @@ #include #include #include -#include +#include #include #include #include -#include #include #include #include @@ -36,7 +35,6 @@ #include #include #include -#include #include @@ -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; diff --git a/libjack/client.c b/libjack/client.c index 1a5d7b7..799f078 100644 --- a/libjack/client.c +++ b/libjack/client.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -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); diff --git a/libjack/port.c b/libjack/port.c index b494462..8c86c49 100644 --- a/libjack/port.c +++ b/libjack/port.c @@ -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; } }