From c3f4fe64ad36443f2b50b0ca0351e74a1dbc261f Mon Sep 17 00:00:00 2001 From: pbd Date: Mon, 23 Feb 2004 19:05:32 +0000 Subject: [PATCH] jack_start_server patch from taybin git-svn-id: svn+ssh://jackaudio.org/trunk/jack@651 0c269be4-1314-0410-8aa9-9f06e86f4224 --- configure.in | 4 +- jack/engine.h | 3 +- jack/jack.h | 1 + jackd/Makefile.am | 2 +- jackd/engine.c | 11 ++++- jackd/jackd.1.in | 3 ++ jackd/jackd.c | 20 +++++--- jackd/jackstart.c | 4 +- libjack/Makefile.am | 3 +- libjack/client.c | 107 +++++++++++++++++++++++++++++++++++++++++- libjack/transclient.c | 2 +- 11 files changed, 140 insertions(+), 20 deletions(-) diff --git a/configure.in b/configure.in index 17064d8..4f7ba3c 100644 --- a/configure.in +++ b/configure.in @@ -14,8 +14,8 @@ dnl micro version = incremented when implementation-only dnl changes are made dnl --- JACK_MAJOR_VERSION=0 -JACK_MINOR_VERSION=94 -JACK_MICRO_VERSION=4 +JACK_MINOR_VERSION=95 +JACK_MICRO_VERSION=0 dnl --- dnl HOWTO: updating the jack protocal version diff --git a/jack/engine.h b/jack/engine.h index 863b340..bcd2137 100644 --- a/jack/engine.h +++ b/jack/engine.h @@ -112,6 +112,7 @@ struct _jack_engine { int rtpriority; char freewheeling; char verbose; + char temporary; int reordered; int watchdog_check; pid_t wait_pid; @@ -147,7 +148,7 @@ struct _jack_engine { /* public functions */ jack_engine_t *jack_engine_new (int real_time, int real_time_priority, - int verbose, int client_timeout, + int temporary, int verbose, int client_timeout, pid_t waitpid, JSList * drivers); int jack_engine_delete (jack_engine_t *); int jack_run (jack_engine_t *engine); diff --git a/jack/jack.h b/jack/jack.h index 8723449..b43779e 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -39,6 +39,7 @@ extern "C" { * * @param client_name of at most jack_client_name_size() characters. * + * @param client_name The name for the new client * @return opaque client handle if successful, otherwise NULL. * * @note Failure generally means that the JACK server is not running. diff --git a/jackd/Makefile.am b/jackd/Makefile.am index 4f845c4..cdf7fe3 100644 --- a/jackd/Makefile.am +++ b/jackd/Makefile.am @@ -21,7 +21,7 @@ endif bin_PROGRAMS = jackd $(CAP_PROGS) -AM_CFLAGS = $(JACK_CFLAGS) -DJACKD_LOCATION=\"$(bindir)/jackd\" +AM_CFLAGS = $(JACK_CFLAGS) -DJACK_LOCATION=\"$(bindir)\" jackd_SOURCES = jackd.c engine.c transengine.c jackd_LDADD = ../libjack/libjack.la -lm -ldl -lrt -lpthread $(CAP_LIBS) diff --git a/jackd/engine.c b/jackd/engine.c index beb6d66..33f44d1 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -875,7 +875,7 @@ jack_remove_clients (jack_engine_t* engine) node = tmp; } - + if (need_sort) { jack_sort_graph (engine); } @@ -1916,7 +1916,7 @@ jack_server_thread (void *arg) } jack_engine_t * -jack_engine_new (int realtime, int rtpriority, int verbose, +jack_engine_new (int realtime, int rtpriority, int temporary, int verbose, int client_timeout, pid_t wait_pid, JSList * drivers) { jack_engine_t *engine; @@ -1948,6 +1948,7 @@ jack_engine_new (int realtime, int rtpriority, int verbose, engine->rtpriority = rtpriority; engine->silent_buffer = 0; engine->verbose = verbose; + engine->temporary = temporary; engine->freewheeling = 0; engine->wait_pid = wait_pid; @@ -2646,6 +2647,12 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) } jack_client_delete (engine, client); + + /* ignore the driver, which counts as a client. */ + if (engine->temporary && (jack_slist_length(engine->clients) <= 1)) { + exit(0); + } + } diff --git a/jackd/jackd.1.in b/jackd/jackd.1.in index a1de871..84454c8 100644 --- a/jackd/jackd.1.in +++ b/jackd/jackd.1.in @@ -54,6 +54,9 @@ requires a kernel with "POSIX draft capabilities" enabled (see the invoke the daemon using \fBjackstart\fR, and later launch JACK clients without running as root. .TP +\fB\-T, \-\-temporary +Will exit once all clients have closed their connections. +.TP \fB\-P, \-\-realtime\-priority \fIint\fR When running \fB\-\-realtime\fR, set the scheduler priority to \fIint\fR. diff --git a/jackd/jackd.c b/jackd/jackd.c index bfe6b25..40c8029 100644 --- a/jackd/jackd.c +++ b/jackd/jackd.c @@ -56,6 +56,7 @@ static sigset_t signals; static jack_engine_t *engine = 0; static int realtime = 0; static int realtime_priority = 10; +static int temporary = 0; static int verbose = 0; static int client_timeout = 500; /* msecs */ @@ -132,7 +133,7 @@ jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params) /* get the engine/driver started */ - if ((engine = jack_engine_new (realtime, realtime_priority, + if ((engine = jack_engine_new (realtime, realtime_priority, temporary, verbose, client_timeout, getpid(), drivers)) == 0) { fprintf (stderr, "cannot create engine\n"); @@ -374,8 +375,8 @@ int main (int argc, char *argv[]) { - jack_driver_desc_t * desc; - const char *options = "-ad:P:vshVRFl:t:"; + jack_driver_desc_t * desc; + const char *options = "-ad:P:vshVRTFl:t:"; struct option long_options[] = { { "driver", 1, 0, 'd' }, @@ -384,12 +385,13 @@ main (int argc, char *argv[]) { "realtime", 0, 0, 'R' }, { "realtime-priority", 1, 0, 'P' }, { "timeout", 1, 0, 't' }, + { "temporary", 0, 0, 'T' }, { "version", 0, 0, 'V' }, { "silent", 0, 0, 's' }, { 0, 0, 0, 0 } }; - int option_index; - int opt; + int opt = 0; + int option_index = 0; int seen_driver = 0; char *driver_name = 0; char **driver_args = 0; @@ -436,10 +438,10 @@ main (int argc, char *argv[]) } } #endif + opterr = 0; while (!seen_driver && (opt = getopt_long (argc, argv, options, - long_options, - &option_index)) != EOF) { + long_options, &option_index)) != EOF) { switch (opt) { case 'd': @@ -463,6 +465,10 @@ main (int argc, char *argv[]) realtime = 1; break; + case 'T': + temporary = 1; + break; + case 't': client_timeout = atoi (optarg); break; diff --git a/jackd/jackstart.c b/jackd/jackstart.c index b24f3aa..23a84fb 100644 --- a/jackd/jackstart.c +++ b/jackd/jackstart.c @@ -43,8 +43,8 @@ #define READ_BLOCKSIZE 4096 -/* JACKD_LOCATION must be passed on the gcc command line */ -static char *jackd_bin_path = JACKD_LOCATION; +/* JACK_LOCATION must be passed on the gcc command line */ +static char *jackd_bin_path = JACK_LOCATION "/jackd"; static char *jackd_md5_sum = JACKD_MD5_SUM; diff --git a/libjack/Makefile.am b/libjack/Makefile.am index 71b8af6..058daaa 100644 --- a/libjack/Makefile.am +++ b/libjack/Makefile.am @@ -14,7 +14,7 @@ lib_LTLIBRARIES = libjack.la noinst_HEADERS = local.h -AM_CFLAGS = $(JACK_CFLAGS) +AM_CFLAGS = $(JACK_CFLAGS) -DJACK_LOCATION=\"$(bindir)\" AM_CXXFLAGS = $(JACK_CFLAGS) libjack_la_CFLAGS = $(AM_CFLAGS) @@ -23,4 +23,3 @@ libjack_la_SOURCES = $(SOURCE_FILES) libjack_la_LIBADD = -lm -lpthread -lrt libjack_la_LDFLAGS = -export-dynamic -version-info @JACK_SO_VERSION@ - diff --git a/libjack/client.c b/libjack/client.c index 8198807..0d2a7bd 100644 --- a/libjack/client.c +++ b/libjack/client.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -392,6 +393,102 @@ server_event_connect (jack_client_t *client) return fd; } +static void +_start_server (void) +{ + FILE* fp = 0; + char filename[255]; + char arguments[255]; + char buffer[255]; + char* command = 0; + size_t pos = 0; + size_t result = 0; + char** argv = 0; + int i = 0; + int good = 0; + int ret; + + + snprintf(filename, 255, "%s/.jackdrc", getenv("HOME")); + fp = fopen(filename, "r"); + + if (!fp) { + fp = fopen("/etc/jackd.conf", "r"); + } + + if (fp) { + ret = fscanf(fp, "%s", buffer); + while(ret != 0 && ret != EOF) { + strcat(arguments, buffer); + strcat(arguments, " "); + ret = fscanf(fp, "%s", buffer); + } + if (strlen(arguments) > 0) { + good = 1; + } + } + + if (!good) { +#if defined(__APPLE__) && defined(__POWERPC__) + command = JACK_LOCATION "/jackd"; + strncpy(arguments, JACK_LOCATION "/jackd -T -d portaudio -p 512", 255); +#elif defined(USE_CAPABILITIES) + command = JACK_LOCATION "/jackstart"; + strncpy(arguments, JACK_LOCATION "/jackstart -T -R -d alsa -d hw:0 -p 512", 255); +#else + command = JACK_LOCATION "/jackd"; + strncpy(arguments, JACK_LOCATION "/jackd -T -d alsa -d hw:0 -p 2048", 255); +#endif + } else { + result = strcspn(arguments, " "); + command = (char*)malloc(result+1); + strncpy(command, arguments, result); + command[result] = '\0'; + } + + argv = (char**)malloc(255); + while(1) { + result = strcspn(arguments+pos, " "); + if (result == 0) { + break; + } + argv[i] = (char*)malloc(result+1); + + strncpy(argv[i], arguments+pos, result); + argv[i][result] = '\0'; + + pos += result+1; + ++i; + } + + execv (command, argv); +} + +int +start_server (void) +{ + pid_t pid1, pid2; + + if (getenv("JACK_NO_START_SERVER")) { + return 1; + } + + switch (pid1 = fork()) { + case -1: + return 1; + + case 0: + switch (pid2 = fork()) { + case -1: + return 1; + case 0: + _start_server(); + } + _exit(0); + } + return 0; +} + static int jack_request_client (ClientType type, const char* client_name, const char* so_name, const char* so_data, @@ -428,7 +525,14 @@ jack_request_client (ClientType type, const char* client_name, } if ((*req_fd = server_connect (0)) < 0) { - goto fail; + if (start_server() == 0) { + sleep(2); + if ((*req_fd = server_connect (0)) < 0) { + goto fail; + } + } else { + goto fail; + } } req.load = TRUE; @@ -1667,7 +1771,6 @@ jack_get_process_done_fd (jack_client_t *client) return client->graph_next_fd; } - void jack_on_shutdown (jack_client_t *client, void (*function)(void *arg), void *arg) { diff --git a/libjack/transclient.c b/libjack/transclient.c index aa8bb26..7139c79 100644 --- a/libjack/transclient.c +++ b/libjack/transclient.c @@ -227,7 +227,7 @@ jack_get_current_transport_frame (const jack_client_t *client) usecs = jack_get_microseconds() - position.usecs; elapsed = (jack_nframes_t) floor ((((float) position.frame_rate) / 1000000.0f) * usecs); - + /* return the estimated transport frame position */