- added --enable-debug configure option * fixed (?) deadlock bug by ignoring errors in fifo cleanup * added solaris stuff, without solaris check * cleaned up some autotools things * added configuration header (config.h) * 0.36.0 (skipping the abortive 0.35.0...) git-svn-id: svn+ssh://jackaudio.org/trunk/jack@234 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
| @@ -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 | |||
| @@ -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 | |||
| ]) | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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) | |||
| @@ -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 | |||
| @@ -36,6 +36,13 @@ | |||
| #include <jack/transport.h> | |||
| #include <jack/cycles.h> | |||
| #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]; | |||
| @@ -23,6 +23,7 @@ | |||
| #include <sys/socket.h> | |||
| #include <sys/poll.h> | |||
| #include <sys/un.h> | |||
| #include <sys/shm.h> | |||
| #include <sys/stat.h> | |||
| #include <errno.h> | |||
| #include <fcntl.h> | |||
| @@ -37,6 +38,8 @@ | |||
| #include <limits.h> | |||
| #include <sys/mman.h> | |||
| #include <config.h> | |||
| #include <jack/internal.h> | |||
| #include <jack/engine.h> | |||
| #include <jack/driver.h> | |||
| @@ -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]; | |||
| @@ -27,6 +27,8 @@ | |||
| #include <errno.h> | |||
| #include <wait.h> | |||
| #include <config.h> | |||
| #include <jack/engine.h> | |||
| #include <jack/internal.h> | |||
| #include <jack/driver.h> | |||
| @@ -32,6 +32,7 @@ | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <config.h> | |||
| #undef _POSIX_SOURCE | |||
| #include <sys/capability.h> | |||
| @@ -33,6 +33,8 @@ | |||
| #include <regex.h> | |||
| #include <math.h> | |||
| #include <config.h> | |||
| #include <jack/jack.h> | |||
| #include <jack/internal.h> | |||
| #include <jack/engine.h> | |||
| @@ -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; | |||
| @@ -24,6 +24,8 @@ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <config.h> | |||
| #include <jack/driver.h> | |||
| #include <jack/internal.h> | |||
| #include <jack/error.h> | |||
| @@ -19,6 +19,9 @@ | |||
| */ | |||
| #include <stdlib.h> | |||
| #include <config.h> | |||
| #include <jack/pool.h> | |||
| void * | |||