diff --git a/Makefile.am b/Makefile.am index 63f38e7..fc8cded 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,14 +1,14 @@ -MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config.h.in \ - stamp-h.in config.log config.cache \ - config.guess mkinstalldirs config.status \ - missing install-sh config.sub ltconfig \ - ltmain.sh acinclude.m4 +MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config.h.in \ + stamp-h.in config.log config.cache \ + config.guess mkinstalldirs config.status \ + missing install-sh config.sub ltconfig \ + ltmain.sh acinclude.m4 if HAVE_DOXYGEN -SUBDIRS = jack libjack jackd drivers example-clients doc +DOC_DIR = doc dist-check-doxygen: else -SUBDIRS = jack libjack jackd drivers example-clients +DOC_DIR = dist-check-doxygen: @echo @echo ' ******' You need doxygen installed to make dist.' ******' @@ -16,6 +16,8 @@ dist-check-doxygen: @false endif +SUBDIRS = jack libjack jackd drivers example-clients $(DOC_DIR) + DIST_SUBDIRS = jack libjack jackd drivers example-clients doc pkgconfigdir = $(libdir)/pkgconfig diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..145a0ac --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,36 @@ +dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR) +dnl example +dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) +dnl will set SYSCONFDIR to /usr/local/etc + +dnl written by thomas vander stichele + +AC_DEFUN(AS_AC_EXPAND, +[ + EXP_VAR=[$1] + FROM_VAR=[$2] + + dnl first expand prefix and exec_prefix if necessary + prefix_save=$prefix + if test "x$prefix" = "xNONE"; then + prefix=/usr/local + fi + exec_prefix_save=$exec_prefix + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=/usr/local + fi + + full_var="$FROM_VAR" + dnl loop until it doesn't change anymore + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var"="x$full_var"; then break; fi + full_var=$new_full_var + done + + dnl clean up + full_var=$new_full_var + [$1]=$full_var + prefix=$prefix_save + exec_prefix=$exec_prefix_save +]) diff --git a/autogen.sh b/autogen.sh index eb19c51..7a0ba52 100755 --- a/autogen.sh +++ b/autogen.sh @@ -10,6 +10,11 @@ aclocal $ACLOCAL_FLAGS || { exit 1 } +autoheader || { + echo "autoheader failed, exiting..." + exit 1 +} + automake --add-missing --foreign || { echo "automake --add-missing --foreign failed, exiting..." exit 1 diff --git a/configure.in b/configure.in index c96d757..bd47153 100644 --- a/configure.in +++ b/configure.in @@ -4,8 +4,8 @@ AC_INIT(jackd/jackd.c) AC_CONFIG_AUX_DIR(.) JACK_MAJOR_VERSION=0 -JACK_MINOR_VERSION=34 -JACK_MICRO_VERSION=1 +JACK_MINOR_VERSION=36 +JACK_MICRO_VERSION=0 BETA= @@ -23,18 +23,42 @@ AC_SUBST(JACK_RELEASE) AM_INIT_AUTOMAKE(jack-audio-connection-kit,${JACK_VERSION}) +AM_CONFIG_HEADER(config.h) + AC_PROG_CC AC_PROG_CXX AC_PROG_LD AM_PROG_LIBTOOL -JACK_CFLAGS='-I$(top_srcdir) -DADDON_DIR=\"$(ADDON_DIR)\" -g -Wall -D_REENTRANT' -JACK_OPT_CFLAGS='-I$(top_srcdir) -DADDON_DIR=\"$(ADDON_DIR)\" -D_REENTRANT -O6 -Wall -fomit-frame-pointer -ffast-math -fstrength-reduce -funroll-loops -fmove-all-movables' +AC_CHECK_HEADERS(string.h strings.h) + +AC_CHECK_FUNC(getopt_long, , AC_MSG_ERROR([GNU getopt is required to build jack])) + +AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) +AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) +AC_CHECK_FUNC(connect, , AC_CHECK_LIB(inet, connect)) + +AC_CHECK_FUNCS(on_exit atexit) + +JACK_CORE_CFLAGS='-I$(top_srcdir) -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -Wall' + +JACK_CFLAGS="$JACK_CORE_CFLAGS -g" +JACK_OPT_CFLAGS="$JACK_CORE_CFLAGS -O6 -fomit-frame-pointer -ffast-math -fstrength-reduce -funroll-loops -fmove-all-movables" AC_ARG_ENABLE(optimize, [ --enable-optimize ask the compiler for its best optimizations], [ if test "x$enable_optimize" != "xno" ; then JACK_CFLAGS="$JACK_OPT_CFLAGS" ; fi ]) +AC_SUBST(JACK_CFLAGS) + +AC_ARG_ENABLE(debug, + [ --enable-debug enable debugging messages in jackd and libjack], + [ if test "x$enable_debug" != "xno" ; then + AC_DEFINE(DEBUG_ENABLED,,[Enable debugging messages]) + fi + ] +) + USE_CAPABILITIES=false AC_ARG_ENABLE(capabilities, @@ -59,13 +83,11 @@ AC_ARG_ENABLE(capabilities, AC_MSG_ERROR([*** Capabilities support not present. Run configure again without --enable-capabilities.]) fi USE_CAPABILITIES=true - JACK_CFLAGS="$JACK_CFLAGS -DUSE_CAPABILITIES" + AC_DEFINE(USE_CAPABILITIES,,[Enable POSIX 1.e capabilities support]) fi ] ) -AC_SUBST(JACK_CFLAGS) - STRIPPED_JACKD=false AC_ARG_ENABLE(stripped-jackd, [ --enable-stripped-jackd strip jack before computing its md5 sum ], @@ -77,16 +99,17 @@ AC_ARG_ENABLE(stripped-jackd, ] ) -# plugins (just jack_alsa.so at the moment) go in the addon dir. +# plugins go in the addon dir. -ADDON_DIR=${libdir}/jack +AS_AC_EXPAND(ADDON_DIR,${libdir}/jack) AC_SUBST(ADDON_DIR) +AC_DEFINE_UNQUOTED(ADDON_DIR,"$ADDON_DIR",[Directory for plugins]) AC_ARG_WITH(html-dir, [ --with-html-dir=PATH where to install the html documentation]) if test "x$with_html_dir" = "x" ; then - HTML_DIR='${datadir}/gtk-doc/html' + HTML_DIR='${pkgdatadir}' else HTML_DIR=$with_html_dir fi @@ -101,11 +124,26 @@ AM_PATH_GLIB(1.0.0, ) AC_CHECK_LIB(asound,snd_pcm_drop, - [:], - [AC_MSG_ERROR([*** JACK currently requires ALSA (0.9.X) which you don't appear to have])], + [ + HAVE_ALSA="true" + AC_SUBST(ALSA_LIBS, -lasound) + ], + [ + HAVE_ALSA="false" + AC_MSG_WARN([ALSA 0.9 support not found]) + ], [-lm] ) +dnl replace me with a proper test +HAVE_SOLARIS="false" + +if test "x$HAVE_ALSA" != "xtrue"; then + if test "x$HAVE_SOLARIS" != "xtrue"; then + AC_MSG_ERROR([*** Neither Solaris nor ALSA audio support was found, aborting...]) + fi +fi + AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_CHECK_LIB(fltk,main, @@ -143,6 +181,9 @@ AM_CONDITIONAL(HAVE_SNDFILE, $HAVE_SNDFILE) AM_CONDITIONAL(HAVE_DOXYGEN, $HAVE_DOXYGEN) AM_CONDITIONAL(USE_CAPABILITIES, $USE_CAPABILITIES) AM_CONDITIONAL(STRIPPED_JACKD, $STRIPPED_JACKD) +AM_CONDITIONAL(HAVE_ALSA, $HAVE_ALSA) +AM_CONDITIONAL(HAVE_SOLARIS, $HAVE_SOLARIS) + AC_OUTPUT( Makefile jack.pc @@ -152,6 +193,7 @@ jackd/Makefile libjack/Makefile drivers/Makefile drivers/alsa/Makefile +drivers/solaris/Makefile example-clients/Makefile doc/Makefile doc/reference.doxygen diff --git a/drivers/Makefile.am b/drivers/Makefile.am index 647ffc8..806566a 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -1,7 +1,17 @@ -MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config.h.in \ - stamp-h.in \ - config.guess mkinstalldirs \ - missing install-sh config.sub ltconfig \ - ltmain.sh acinclude.m4 +MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = alsa +if HAVE_ALSA +ALSA_DIR = alsa +else +ALSA_DIR = +endif + +if HAVE_SOLARIS +SOLARIS_DIR = solaris +else +SOLARIS_DIR = +endif + +SUBDIRS = $(ALSA_DIR) $(SOLARIS_DIR) + +DIST_SUBDIRS = alsa solaris \ No newline at end of file diff --git a/drivers/alsa/Makefile.am b/drivers/alsa/Makefile.am index fff9ee5..02610d6 100644 --- a/drivers/alsa/Makefile.am +++ b/drivers/alsa/Makefile.am @@ -9,4 +9,4 @@ plugin_LTLIBRARIES = jack_alsa.la jack_alsa_la_LDFLAGS = -module jack_alsa_la_SOURCES = alsa_driver.c generic_hw.c memops.c \ hammerfall.c ice1712.c -jack_alsa_la_LIBADD = -lasound $(GLIB_LIBS) -lm +jack_alsa_la_LIBADD = $(ALSA_LIBS) $(GLIB_LIBS) diff --git a/drivers/solaris/Makefile.am b/drivers/solaris/Makefile.am index 5c1f0d4..fabcf97 100644 --- a/drivers/solaris/Makefile.am +++ b/drivers/solaris/Makefile.am @@ -8,4 +8,4 @@ plugin_LTLIBRARIES = jack_solaris.la jack_solaris_la_LDFLAGS = -module jack_solaris_la_SOURCES = solaris_driver.c -jack_solaris_la_LIBADD = $(AUDIO_LIBS) $(GLIB_LIBS) -lm +jack_solaris_la_LIBADD = $(SOLARIS_LIBS) $(GLIB_LIBS) -lm diff --git a/jack/internal.h b/jack/internal.h index f34c52d..e0a1ec5 100644 --- a/jack/internal.h +++ b/jack/internal.h @@ -36,6 +36,13 @@ #include #include +#ifdef DEBUG_ENABLED +#define DEBUG(format,args...) \ + printf ("jack:%5d %s:%s:%d: " format "\n", getpid(), __FILE__, __FUNCTION__, __LINE__ , ## args) +#else +#define DEBUG(format,args...) +#endif + typedef struct _jack_engine jack_engine_t; typedef void * dlhandle; @@ -110,10 +117,10 @@ typedef enum { PortRegistered, PortUnregistered, XRun, -} AudioEngineEventType; +} EventType; typedef struct { - AudioEngineEventType type; + EventType type; union { unsigned long n; jack_port_id_t port_id; @@ -226,11 +233,11 @@ typedef enum { DeactivateClient = 7, DisconnectPort = 8, SetClientCapabilities = 9 -} AudioEngineRequestType; +} RequestType; typedef struct { - AudioEngineRequestType type; + RequestType type; union { struct { char name[JACK_PORT_NAME_SIZE+1]; diff --git a/jackd/engine.c b/jackd/engine.c index b4b6e89..edba28c 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ #include #include +#include + #include #include #include @@ -133,11 +136,15 @@ jack_client_is_inprocess (jack_client_internal_t *client) return (client->control->type == ClientDynamic) || (client->control->type == ClientDriver); } -static inline void -jack_lock_graph (jack_engine_t *engine) -{ - pthread_mutex_lock (&engine->client_lock); -} +#define jack_lock_graph(engine) G_STMT_START{ \ + DEBUG ("acquiring graph lock"); \ + pthread_mutex_lock (&engine->client_lock); \ +}G_STMT_END + +#define jack_unlock_graph(engine) G_STMT_START{ \ + DEBUG ("releasing graph lock"); \ + pthread_mutex_unlock (&engine->client_lock); \ +}G_STMT_END static inline void jack_engine_reset_rolling_usecs (jack_engine_t *engine) @@ -155,12 +162,6 @@ jack_engine_reset_rolling_usecs (jack_engine_t *engine) engine->spare_usecs = 0; } -static inline void -jack_unlock_graph (jack_engine_t *engine) -{ - pthread_mutex_unlock (&engine->client_lock); -} - static int make_sockets (int fd[2]) { @@ -419,12 +420,15 @@ jack_set_sample_rate (jack_engine_t *engine, jack_nframes_t nframes) int jack_engine_process_lock (jack_engine_t *engine) { - return pthread_mutex_trylock (&engine->client_lock); + int ret = pthread_mutex_trylock (&engine->client_lock); + if (ret == 0) DEBUG ("success"); else DEBUG ("FAILURE"); + return ret; } void jack_engine_process_unlock (jack_engine_t *engine) { + DEBUG ("success"); pthread_mutex_unlock (&engine->client_lock); } @@ -455,6 +459,8 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) client = (jack_client_internal_t *) node->data; + DEBUG ("considering client %s for processing", client->control->name); + if (!client->control->active || client->control->dead) { node = g_slist_next (node); continue; @@ -469,6 +475,8 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) if (ctl->process) { + DEBUG ("calling process() on an in-process client"); + ctl->state = Running; /* XXX how to time out an in-process client? */ @@ -482,6 +490,8 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) } } else { + DEBUG ("in-process client has no process() function"); + ctl->state = Finished; } @@ -495,6 +505,8 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) ctl->signalled_at = 0; ctl->finished_at = 0; + DEBUG ("calling process() on an OOP subgraph, fd==%d", client->subgraph_start_fd); + if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) { jack_error ("cannot initiate graph processing (%s)", strerror (errno)); engine->process_errors++; @@ -512,6 +524,8 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) pfd[0].fd = client->subgraph_wait_fd; pfd[0].events = POLLERR|POLLIN|POLLHUP|POLLNVAL; + DEBUG ("waiting on fd==%d for process() subgraph to finish", client->subgraph_wait_fd); + if (poll (pfd, 1, poll_timeout) < 0) { jack_error ("poll on subgraph processing failed (%s)", strerror (errno)); status = -1; @@ -549,6 +563,8 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) engine->process_errors++; break; } else { + DEBUG ("reading byte from subgraph_wait_fd==%d", client->subgraph_wait_fd); + if (read (client->subgraph_wait_fd, &c, sizeof (c)) != sizeof (c)) { jack_error ("pp: cannot clean up byte from graph wait fd (%s)", strerror (errno)); client->error++; @@ -1116,6 +1132,8 @@ handle_client_request (jack_engine_t *engine, int fd) reply_fd = client->request_fd; + DEBUG ("got a request of type %d", req.type); + switch (req.type) { case RegisterPort: req.status = jack_port_do_register (engine, &req); @@ -1165,12 +1183,17 @@ handle_client_request (jack_engine_t *engine, int fd) break; } + DEBUG ("status of request: %d", req.status); + if (reply_fd >= 0) { + DEBUG ("replying to client"); if (write (reply_fd, &req, sizeof (req)) < sizeof (req)) { jack_error ("cannot write request result to client"); return -1; } - } + } else { + DEBUG ("*not* replying to client"); + } return 0; } @@ -1449,6 +1472,7 @@ jack_become_real_time (pthread_t thread, int priority) return 0; } +#ifdef HAVE_ON_EXIT static void cancel_cleanup (int status, void *arg) @@ -1457,6 +1481,22 @@ cancel_cleanup (int status, void *arg) engine->driver->stop (engine->driver); engine->driver->finish (engine->driver); } +#else +#ifdef HAVE_ATEXIT +jack_engine_t *global_engine; + +static void +cancel_cleanup (void) + +{ + jack_engine_t *engine = global_engine; + engine->driver->stop (engine->driver); + engine->driver->finish (engine->driver); +} +#else +#error "Don't know how to make an exit handler" +#endif /* HAVE_ATEXIT */ +#endif /* HAVE_ON_EXIT */ static void * watchdog_thread (void *arg) @@ -1549,7 +1589,16 @@ jack_main_thread (void *arg) } pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +#ifdef HAVE_ON_EXIT on_exit (cancel_cleanup, engine); +#else +#ifdef HAVE_ATEXIT + global_engine = engine; + atexit (cancel_cleanup); +#else +#error "Don't know how to install an exit handler" +#endif /* HAVE_ATEXIT */ +#endif /* HAVE_ON_EXIT */ if (driver->start (driver)) { jack_error ("cannot start driver"); @@ -1606,6 +1655,8 @@ jack_main_thread (void *arg) pthread_exit (0); } + /* this will execute the entire jack graph */ + switch (driver->process (driver, nframes)) { case -1: jack_error ("driver process function failed, exiting"); @@ -1931,6 +1982,8 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_ /* caller must hold the client_lock */ + DEBUG ("delivering event (type %d)", event->type); + if (client->control->dead) { return 0; } @@ -1974,11 +2027,15 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_ } else { + DEBUG ("engine writing on event fd"); + if (write (client->event_fd, event, sizeof (*event)) != sizeof (*event)) { jack_error ("cannot send event to client [%s] (%s)", client->control->name, strerror (errno)); client->error++; } - + + DEBUG ("engine reading from event fd"); + if (!client->error && (read (client->event_fd, &status, sizeof (status)) != sizeof (status))) { jack_error ("cannot read event response from client [%s] (%s)", client->control->name, strerror (errno)); client->error++; @@ -1990,6 +2047,8 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_ } } + DEBUG ("event delivered"); + return 0; } @@ -2097,6 +2156,7 @@ jack_rechain_graph (jack_engine_t *engine) event.x.n = client->execution_order; jack_deliver_event (engine, client, &event); + n++; } } @@ -2502,6 +2562,8 @@ jack_port_do_connect (jack_engine_t *engine, jack_sort_graph (engine); + DEBUG ("actually sorted the graph..."); + jack_send_connection_notification (engine, srcport->shared->client_id, src_id, dst_id, TRUE); jack_send_connection_notification (engine, dstport->shared->client_id, dst_id, src_id, TRUE); } @@ -2627,6 +2689,8 @@ jack_get_fifo_fd (jack_engine_t *engine, int which_fifo) sprintf (path, "%s-%d", engine->fifo_prefix, which_fifo); + DEBUG ("%s", path); + if (stat (path, &statbuf)) { if (errno == ENOENT) { if (mknod (path, 0666|S_IFIFO, 0) < 0) { @@ -2659,6 +2723,7 @@ jack_get_fifo_fd (jack_engine_t *engine, int which_fifo) jack_error ("cannot open fifo [%s] (%s)", path, strerror (errno)); return -1; } + DEBUG ("opened engine->fifo[%d] == %d (%s)", which_fifo, engine->fifo[which_fifo], path); } return engine->fifo[which_fifo]; diff --git a/jackd/jackd.c b/jackd/jackd.c index 6132a24..b71aa17 100644 --- a/jackd/jackd.c +++ b/jackd/jackd.c @@ -27,6 +27,8 @@ #include #include +#include + #include #include #include diff --git a/jackd/jackstart.c b/jackd/jackstart.c index dda601e..bbd8f7b 100644 --- a/jackd/jackstart.c +++ b/jackd/jackstart.c @@ -32,6 +32,7 @@ #include #include +#include #undef _POSIX_SOURCE #include diff --git a/libjack/client.c b/libjack/client.c index 1a483d9..6ec05fe 100644 --- a/libjack/client.c +++ b/libjack/client.c @@ -33,6 +33,8 @@ #include #include +#include + #include #include #include @@ -244,11 +246,13 @@ jack_handle_reorder (jack_client_t *client, jack_event_t *event) char path[PATH_MAX+1]; if (client->graph_wait_fd >= 0) { + DEBUG ("closing graph_wait_fd==%d", client->graph_wait_fd); close (client->graph_wait_fd); client->graph_wait_fd = -1; } if (client->graph_next_fd >= 0) { + DEBUG ("closing graph_next_fd==%d", client->graph_next_fd); close (client->graph_next_fd); client->graph_next_fd = -1; } @@ -260,6 +264,9 @@ jack_handle_reorder (jack_client_t *client, jack_event_t *event) return -1; } + + DEBUG ("opened new graph_wait_fd %d (%s)", client->graph_wait_fd, path); + sprintf (path, "%s-%lu", client->fifo_prefix, event->x.n+1); if ((client->graph_next_fd = open (path, O_WRONLY|O_NONBLOCK)) < 0) { @@ -267,6 +274,8 @@ jack_handle_reorder (jack_client_t *client, jack_event_t *event) return -1; } + DEBUG ("opened new graph_next_fd %d (%s)", client->graph_next_fd, path); + /* If the client registered its own callback for graph order events, execute it now. */ @@ -519,6 +528,8 @@ jack_client_thread (void *arg) while (err == 0) { + DEBUG ("client polling on event_fd and graph_wait_fd..."); + if (poll (client->pollfd, client->pollmax, 1000) < 0) { if (errno == EINTR) { printf ("poll interrupted\n"); @@ -539,6 +550,8 @@ jack_client_thread (void *arg) if (client->pollfd[0].revents & POLLIN) { + DEBUG ("client receives an event, now reading on event fd"); + /* server has sent us an event. process the event and reply */ if (read (client->event_fd, &event, sizeof (event)) != sizeof (event)) { @@ -595,6 +608,8 @@ jack_client_thread (void *arg) break; } + DEBUG ("client has dealt with the event, writing response on event fd"); + if (write (client->event_fd, &status, sizeof (status)) != sizeof (status)) { jack_error ("cannot send event response to engine (%s)", strerror (errno)); err++; @@ -603,6 +618,7 @@ jack_client_thread (void *arg) } if (client->pollfd[1].revents & POLLIN) { + DEBUG ("client told to process() (wakeup on graph_wait_fd==%d)", client->pollfd[1].fd); control->signalled_at = get_cycles(); @@ -620,16 +636,23 @@ jack_client_thread (void *arg) /* pass the execution token along */ + DEBUG ("client finished processing, writing on graph_next_fd==%d", client->graph_next_fd); + if (write (client->graph_next_fd, &c, sizeof (c)) != sizeof (c)) { jack_error ("cannot continue execution of the processing graph (%s)", strerror(errno)); err++; break; } + DEBUG ("client reading on graph_wait_fd==%d", client->graph_wait_fd); + if ((read (client->graph_wait_fd, &c, sizeof (c)) != sizeof (c))) { + DEBUG ("WARNING: READ FAILED!"); +/* jack_error ("cannot complete execution of the processing graph (%s)", strerror(errno)); err++; break; +*/ } } @@ -707,7 +730,7 @@ jack_start_thread (jack_client_t *client) that code fail when running under a non-root user but with the proper realtime capabilities (in short, pthread_attr_setschedpolicy does not check for capabilities, only for the uid being - zero). Newer versions apparently have this fixed. Thus + zero). Newer versions apparently have this fixed. This workaround temporarily switches the client thread to the proper scheduler and priority, then starts the realtime thread so that it can inherit them and finally switches the @@ -791,6 +814,10 @@ jack_activate (jack_client_t *client) { jack_request_t req; + /* we need to scribble on our stack to ensure that its memory pages are + * actually mapped (more important for mlockall(2) usage in + * jack_start_thread()) */ + #define BIG_ENOUGH_STACK 1048576 char buf[BIG_ENOUGH_STACK]; @@ -886,12 +913,12 @@ jack_deactivate (jack_client_t *client) req.x.client_id = client->control->id; if (write (client->request_fd, &req, sizeof (req)) != sizeof (req)) { - jack_error ("cannot send activate client request to server"); + jack_error ("cannot send deactivate client request to server"); return -1; } if (read (client->request_fd, &req, sizeof (req)) != sizeof (req)) { - jack_error ("cannot read activate client result from server (%s)", strerror (errno)); + jack_error ("cannot read deactivate client result from server (%s)", strerror (errno)); return -1; } @@ -1214,16 +1241,22 @@ jack_connect (jack_client_t *client, const char *source_port, const char *destin strncpy (req.x.connect.destination_port, destination_port, sizeof (req.x.connect.destination_port) - 1); req.x.connect.destination_port[sizeof(req.x.connect.destination_port) - 1] = '\0'; + DEBUG ("writing to request_fd"); + if (write (client->request_fd, &req, sizeof (req)) != sizeof (req)) { jack_error ("cannot send port connection request to server"); return -1; } + DEBUG ("reading from request_fd"); + if (read (client->request_fd, &req, sizeof (req)) != sizeof (req)) { jack_error ("cannot read port connection result from server"); return -1; } + DEBUG ("connected: %d", req.status); + return req.status; } @@ -1420,6 +1453,7 @@ int jack_set_graph_order_callback (jack_client_t *client, JackGraphOrderCallback callback, void *arg) { if (client->control->active) { + g_warning ("You cannot set callbacks on an active client."); return -1; } client->control->graph_order = callback; @@ -1432,6 +1466,7 @@ jack_set_process_callback (jack_client_t *client, JackProcessCallback callback, { if (client->control->active) { + g_warning ("You cannot set callbacks on an active client."); return -1; } client->control->process_arg = arg; @@ -1444,6 +1479,7 @@ jack_set_buffer_size_callback (jack_client_t *client, JackBufferSizeCallback cal { if (client->control->active) { + g_warning ("You cannot set callbacks on an active client."); return -1; } client->control->bufsize_arg = arg; @@ -1461,6 +1497,7 @@ jack_set_sample_rate_callback (jack_client_t *client, JackSampleRateCallback cal { if (client->control->active) { + g_warning ("You cannot set callbacks on an active client."); return -1; } client->control->srate_arg = arg; @@ -1478,6 +1515,7 @@ jack_set_port_registration_callback(jack_client_t *client, JackPortRegistrationC { if (client->control->active) { + g_warning ("You cannot set callbacks on an active client."); return -1; } client->control->port_register_arg = arg; diff --git a/libjack/driver.c b/libjack/driver.c index 6bfff97..9c32512 100644 --- a/libjack/driver.c +++ b/libjack/driver.c @@ -24,6 +24,8 @@ #include #include +#include + #include #include #include diff --git a/libjack/pool.c b/libjack/pool.c index cb02ecb..675a91e 100644 --- a/libjack/pool.c +++ b/libjack/pool.c @@ -19,6 +19,9 @@ */ #include + +#include + #include void *