netjack changes from torben (packet loss handling leads to "dummy" backend-like behav...
[jack.git] / jackd / jackd.c
blobc38c1e5237ae0c56819945e0e0d147ffc2d6607b
1 /* -*- mode: c; c-file-style: "bsd"; -*- */
2 /*
3 Copyright (C) 2001-2005 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <config.h>
23 #include <stdio.h>
24 #include <ctype.h>
25 #include <signal.h>
26 #include <getopt.h>
27 #include <sys/types.h>
28 #include <sys/shm.h>
29 #include <sys/wait.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <stdlib.h>
33 #include <dirent.h>
34 #include <dlfcn.h>
36 #include <jack/engine.h>
37 #include <jack/internal.h>
38 #include <jack/driver.h>
39 #include <jack/shm.h>
40 #include <jack/driver_parse.h>
41 #include <jack/messagebuffer.h>
43 #ifdef USE_CAPABILITIES
45 #include <sys/stat.h>
46 /* capgetp and capsetp are linux only extensions, not posix */
47 #undef _POSIX_SOURCE
48 #include <sys/capability.h>
49 #include <jack/start.h>
51 static struct stat pipe_stat;
53 #endif /* USE_CAPABILITIES */
55 static JSList *drivers = NULL;
56 static sigset_t signals;
57 static jack_engine_t *engine = NULL;
58 static char *server_name = NULL;
59 static int realtime = 0;
60 static int realtime_priority = 10;
61 static int do_mlock = 1;
62 static int temporary = 0;
63 static int verbose = 0;
64 static int client_timeout = 0; /* msecs; if zero, use period size. */
65 static unsigned int port_max = 256;
66 static int do_unlock = 0;
67 static jack_nframes_t frame_time_offset = 0;
68 static int nozombies = 0;
70 static void
71 do_nothing_handler (int sig)
73 /* this is used by the child (active) process, but it never
74 gets called unless we are already shutting down after
75 another signal.
77 char buf[64];
78 snprintf (buf, sizeof(buf),
79 "received signal %d during shutdown (ignored)\n", sig);
80 write (1, buf, strlen (buf));
83 static int
84 jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params)
86 int sig;
87 int i;
88 sigset_t allsignals;
89 struct sigaction action;
90 int waiting;
92 /* ensure that we are in our own process group so that
93 kill (SIG, -pgrp) does the right thing.
96 setsid ();
98 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
100 /* what's this for?
102 POSIX says that signals are delivered like this:
104 * if a thread has blocked that signal, it is not
105 a candidate to receive the signal.
106 * of all threads not blocking the signal, pick
107 one at random, and deliver the signal.
109 this means that a simple-minded multi-threaded program can
110 expect to get POSIX signals delivered randomly to any one
111 of its threads,
113 here, we block all signals that we think we might receive
114 and want to catch. all "child" threads will inherit this
115 setting. if we create a thread that calls sigwait() on the
116 same set of signals, implicitly unblocking all those
117 signals. any of those signals that are delivered to the
118 process will be delivered to that thread, and that thread
119 alone. this makes cleanup for a signal-driven exit much
120 easier, since we know which thread is doing it and more
121 importantly, we are free to call async-unsafe functions,
122 because the code is executing in normal thread context
123 after a return from sigwait().
126 sigemptyset (&signals);
127 sigaddset(&signals, SIGHUP);
128 sigaddset(&signals, SIGINT);
129 sigaddset(&signals, SIGQUIT);
130 sigaddset(&signals, SIGPIPE);
131 sigaddset(&signals, SIGTERM);
132 sigaddset(&signals, SIGUSR1);
133 sigaddset(&signals, SIGUSR2);
135 /* all child threads will inherit this mask unless they
136 * explicitly reset it
139 pthread_sigmask (SIG_BLOCK, &signals, 0);
141 if (!realtime && client_timeout == 0)
142 client_timeout = 500; /* 0.5 sec; usable when non realtime. */
144 /* get the engine/driver started */
146 if ((engine = jack_engine_new (realtime, realtime_priority,
147 do_mlock, do_unlock, server_name,
148 temporary, verbose, client_timeout,
149 port_max, getpid(), frame_time_offset,
150 nozombies, drivers)) == 0) {
151 jack_error ("cannot create engine");
152 return -1;
155 jack_info ("loading driver ..");
157 if (jack_engine_load_driver (engine, driver_desc, driver_params)) {
158 jack_error ("cannot load driver module %s",
159 driver_desc->name);
160 goto error;
163 if (engine->driver->start (engine->driver) != 0) {
164 jack_error ("cannot start driver");
165 goto error;
168 /* install a do-nothing handler because otherwise pthreads
169 behaviour is undefined when we enter sigwait.
172 sigfillset (&allsignals);
173 action.sa_handler = do_nothing_handler;
174 action.sa_mask = allsignals;
175 action.sa_flags = SA_RESTART|SA_RESETHAND;
177 for (i = 1; i < NSIG; i++) {
178 if (sigismember (&signals, i)) {
179 sigaction (i, &action, 0);
183 if (verbose) {
184 jack_info ("%d waiting for signals", getpid());
187 waiting = TRUE;
189 while (waiting) {
190 sigwait (&signals, &sig);
192 jack_info ("jack main caught signal %d", sig);
194 switch (sig) {
195 case SIGUSR1:
196 jack_dump_configuration(engine, 1);
197 break;
198 case SIGUSR2:
199 /* driver exit */
200 waiting = FALSE;
201 break;
202 default:
203 waiting = FALSE;
204 break;
208 if (sig != SIGSEGV) {
210 /* unblock signals so we can see them during shutdown.
211 this will help prod developers not to lose sight of
212 bugs that cause segfaults etc. during shutdown.
214 sigprocmask (SIG_UNBLOCK, &signals, 0);
217 jack_engine_delete (engine);
218 return 1;
220 error:
221 jack_engine_delete (engine);
222 return -1;
225 static jack_driver_desc_t *
226 jack_drivers_get_descriptor (JSList * drivers, const char * sofile)
228 jack_driver_desc_t * descriptor, * other_descriptor;
229 JackDriverDescFunction so_get_descriptor;
230 JSList * node;
231 void * dlhandle;
232 char * filename;
233 const char * dlerr;
234 int err;
235 char* driver_dir;
237 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
238 driver_dir = ADDON_DIR;
240 filename = malloc (strlen (driver_dir) + 1 + strlen (sofile) + 1);
241 sprintf (filename, "%s/%s", driver_dir, sofile);
243 if (verbose) {
244 jack_info ("getting driver descriptor from %s", filename);
247 if ((dlhandle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL)) == NULL) {
248 jack_error ("could not open driver .so '%s': %s\n", filename, dlerror ());
249 free (filename);
250 return NULL;
253 so_get_descriptor = (JackDriverDescFunction)
254 dlsym (dlhandle, "driver_get_descriptor");
256 if ((dlerr = dlerror ()) != NULL) {
257 jack_error("%s", dlerr);
258 dlclose (dlhandle);
259 free (filename);
260 return NULL;
263 if ((descriptor = so_get_descriptor ()) == NULL) {
264 jack_error ("driver from '%s' returned NULL descriptor\n", filename);
265 dlclose (dlhandle);
266 free (filename);
267 return NULL;
270 if ((err = dlclose (dlhandle)) != 0) {
271 jack_error ("error closing driver .so '%s': %s\n", filename, dlerror ());
274 /* check it doesn't exist already */
275 for (node = drivers; node; node = jack_slist_next (node)) {
276 other_descriptor = (jack_driver_desc_t *) node->data;
278 if (strcmp (descriptor->name, other_descriptor->name) == 0) {
279 jack_error ("the drivers in '%s' and '%s' both have the name '%s'; using the first\n",
280 other_descriptor->file, filename, other_descriptor->name);
281 /* FIXME: delete the descriptor */
282 free (filename);
283 return NULL;
287 snprintf (descriptor->file, sizeof(descriptor->file), "%s", filename);
288 free (filename);
290 return descriptor;
293 static JSList *
294 jack_drivers_load ()
296 struct dirent * dir_entry;
297 DIR * dir_stream;
298 const char * ptr;
299 int err;
300 JSList * driver_list = NULL;
301 jack_driver_desc_t * desc;
302 char* driver_dir;
304 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
305 driver_dir = ADDON_DIR;
308 /* search through the driver_dir and add get descriptors
309 from the .so files in it */
310 dir_stream = opendir (driver_dir);
311 if (!dir_stream) {
312 jack_error ("could not open driver directory %s: %s\n",
313 driver_dir, strerror (errno));
314 return NULL;
317 while ( (dir_entry = readdir (dir_stream)) ) {
318 /* check the filename is of the right format */
319 if (strncmp ("jack_", dir_entry->d_name, 5) != 0) {
320 continue;
323 ptr = strrchr (dir_entry->d_name, '.');
324 if (!ptr) {
325 continue;
327 ptr++;
328 if (strncmp ("so", ptr, 2) != 0) {
329 continue;
332 desc = jack_drivers_get_descriptor (drivers, dir_entry->d_name);
333 if (desc) {
334 driver_list = jack_slist_append (driver_list, desc);
338 err = closedir (dir_stream);
339 if (err) {
340 jack_error ("error closing driver directory %s: %s\n",
341 driver_dir, strerror (errno));
344 if (!driver_list) {
345 jack_error ("could not find any drivers in %s!\n", driver_dir);
346 return NULL;
349 return driver_list;
352 static void copyright (FILE* file)
354 fprintf (file, "jackd " VERSION "\n"
355 "Copyright 2001-2005 Paul Davis and others.\n"
356 "jackd comes with ABSOLUTELY NO WARRANTY\n"
357 "This is free software, and you are welcome to redistribute it\n"
358 "under certain conditions; see the file COPYING for details\n\n");
361 static void usage (FILE *file)
363 copyright (file);
364 fprintf (file, "\n"
365 "usage: jackd [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
366 " [ --name OR -n server-name ]\n"
367 " [ --no-mlock OR -m ]\n"
368 " [ --unlock OR -u ]\n"
369 " [ --timeout OR -t client-timeout-in-msecs ]\n"
370 " [ --port-max OR -p maximum-number-of-ports]\n"
371 " [ --debug-timer OR -D ]\n"
372 " [ --verbose OR -v ]\n"
373 " [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n"
374 " [ --replace-registry OR -r ]\n"
375 " [ --silent OR -s ]\n"
376 " [ --version OR -V ]\n"
377 " [ --nozombies OR -Z ]\n"
378 " -d backend [ ... backend args ... ]\n"
379 " The backend can be `alsa', `coreaudio', `dummy',\n"
380 " `freebob', `oss', `sun', or `portaudio'.\n\n"
381 " jackd -d backend --help\n"
382 " to display options for each backend\n\n");
385 static jack_driver_desc_t *
386 jack_find_driver_descriptor (const char * name)
388 jack_driver_desc_t * desc = 0;
389 JSList * node;
391 for (node = drivers; node; node = jack_slist_next (node)) {
392 desc = (jack_driver_desc_t *) node->data;
394 if (strcmp (desc->name, name) != 0) {
395 desc = NULL;
396 } else {
397 break;
401 return desc;
404 static void
405 jack_cleanup_files (const char *server_name)
407 DIR *dir;
408 struct dirent *dirent;
409 char dir_name[PATH_MAX+1] = "";
410 jack_server_dir (server_name, dir_name);
412 /* On termination, we remove all files that jackd creates so
413 * subsequent attempts to start jackd will not believe that an
414 * instance is already running. If the server crashes or is
415 * terminated with SIGKILL, this is not possible. So, cleanup
416 * is also attempted when jackd starts.
418 * There are several tricky issues. First, the previous JACK
419 * server may have run for a different user ID, so its files
420 * may be inaccessible. This is handled by using a separate
421 * JACK_TMP_DIR subdirectory for each user. Second, there may
422 * be other servers running with different names. Each gets
423 * its own subdirectory within the per-user directory. The
424 * current process has already registered as `server_name', so
425 * we know there is no other server actively using that name.
428 /* nothing to do if the server directory does not exist */
429 if ((dir = opendir (dir_name)) == NULL) {
430 return;
433 /* unlink all the files in this directory, they are mine */
434 while ((dirent = readdir (dir)) != NULL) {
436 char fullpath[PATH_MAX+1];
438 if ((strcmp (dirent->d_name, ".") == 0)
439 || (strcmp (dirent->d_name, "..") == 0)) {
440 continue;
443 snprintf (fullpath, sizeof (fullpath), "%s/%s",
444 dir_name, dirent->d_name);
446 if (unlink (fullpath)) {
447 jack_error ("cannot unlink `%s' (%s)", fullpath,
448 strerror (errno));
452 closedir (dir);
454 /* now, delete the per-server subdirectory, itself */
455 if (rmdir (dir_name)) {
456 jack_error ("cannot remove `%s' (%s)", dir_name,
457 strerror (errno));
460 /* finally, delete the per-user subdirectory, if empty */
461 if (rmdir (jack_user_dir ())) {
462 if (errno != ENOTEMPTY) {
463 jack_error ("cannot remove `%s' (%s)",
464 jack_user_dir (), strerror (errno));
469 static void
470 maybe_use_capabilities ()
472 #ifdef USE_CAPABILITIES
473 int status;
475 /* check to see if there is a pipe in the right descriptor */
476 if ((status = fstat (PIPE_WRITE_FD, &pipe_stat)) == 0 &&
477 S_ISFIFO(pipe_stat.st_mode)) {
479 /* tell jackstart we are up and running */
480 char c = 1;
482 if (write (PIPE_WRITE_FD, &c, 1) != 1) {
483 jack_error ("cannot write to jackstart sync "
484 "pipe %d (%s)", PIPE_WRITE_FD,
485 strerror (errno));
488 if (close(PIPE_WRITE_FD) != 0) {
489 jack_error("jackd: error on startup pipe close: %s",
490 strerror (errno));
491 } else {
492 /* wait for jackstart process to set our capabilities */
493 if (wait (&status) == -1) {
494 jack_error ("jackd: wait for startup "
495 "process exit failed");
497 if (!WIFEXITED (status) || WEXITSTATUS (status)) {
498 jack_error ("jackd: jackstart did not "
499 "exit cleanly");
500 exit (1);
504 #endif /* USE_CAPABILITIES */
507 int
508 main (int argc, char *argv[])
511 jack_driver_desc_t * desc;
512 const char *options = "-ad:P:uvshVRZTFlt:mn:p:c:";
513 struct option long_options[] =
515 { "driver", 1, 0, 'd' },
516 { "verbose", 0, 0, 'v' },
517 { "help", 0, 0, 'h' },
518 { "tmpdir-location", 0, 0, 'l' },
519 { "port-max", 1, 0, 'p' },
520 { "no-mlock", 0, 0, 'm' },
521 { "name", 1, 0, 'n' },
522 { "unlock", 0, 0, 'u' },
523 { "realtime", 0, 0, 'R' },
524 { "replace-registry", 0, 0, 'r' },
525 { "realtime-priority", 1, 0, 'P' },
526 { "timeout", 1, 0, 't' },
527 { "temporary", 0, 0, 'T' },
528 { "version", 0, 0, 'V' },
529 { "silent", 0, 0, 's' },
530 { "clock-source", 1, 0, 'c' },
531 { "nozombies", 0, 0, 'Z' },
532 { 0, 0, 0, 0 }
534 int opt = 0;
535 int option_index = 0;
536 int seen_driver = 0;
537 char *driver_name = NULL;
538 char **driver_args = NULL;
539 JSList * driver_params;
540 int driver_nargs = 1;
541 int show_version = 0;
542 int replace_registry = 0;
543 int i;
544 int rc;
546 setvbuf (stdout, NULL, _IOLBF, 0);
548 maybe_use_capabilities ();
550 opterr = 0;
551 while (!seen_driver &&
552 (opt = getopt_long (argc, argv, options,
553 long_options, &option_index)) != EOF) {
554 switch (opt) {
556 case 'c':
557 if (tolower (optarg[0]) == 'h') {
558 clock_source = JACK_TIMER_HPET;
559 } else if (tolower (optarg[0]) == 'c') {
560 clock_source = JACK_TIMER_CYCLE_COUNTER;
561 } else if (tolower (optarg[0]) == 's') {
562 clock_source = JACK_TIMER_SYSTEM_CLOCK;
563 } else {
564 usage (stderr);
565 return -1;
567 break;
569 case 'd':
570 seen_driver = 1;
571 driver_name = optarg;
572 break;
574 case 'D':
575 frame_time_offset = JACK_MAX_FRAMES - atoi(optarg);
576 break;
578 case 'l':
579 /* special flag to allow libjack to determine jackd's idea of where tmpdir is */
580 printf ("%s\n", jack_tmpdir);
581 exit (0);
583 case 'm':
584 do_mlock = 0;
585 break;
587 case 'n':
588 server_name = optarg;
589 break;
591 case 'p':
592 port_max = (unsigned int) atol (optarg);
593 break;
595 case 'P':
596 realtime_priority = atoi (optarg);
597 break;
599 case 'r':
600 replace_registry = 1;
601 break;
603 case 'R':
604 realtime = 1;
605 break;
607 case 's':
608 jack_set_error_function (silent_jack_error_callback);
609 break;
611 case 'T':
612 temporary = 1;
613 break;
615 case 't':
616 client_timeout = atoi (optarg);
617 break;
619 case 'u':
620 do_unlock = 1;
621 break;
623 case 'v':
624 verbose = 1;
625 break;
627 case 'V':
628 show_version = 1;
629 break;
631 case 'Z':
632 nozombies = 1;
633 break;
635 default:
636 jack_error ("Unknown option character %c",
637 optopt);
638 /*fallthru*/
639 case 'h':
640 usage (stdout);
641 return -1;
645 if (show_version) {
646 printf ( "jackd version " VERSION
647 " tmpdir " DEFAULT_TMP_DIR
648 " protocol " PROTOCOL_VERSION
649 "\n");
650 return -1;
653 if (realtime && (client_timeout >= JACKD_WATCHDOG_TIMEOUT)) {
654 usage (stderr);
655 fprintf (stderr, "In realtime mode (-R) the client timeout must be smaller than the watchdog timeout (%ims).\n", JACKD_WATCHDOG_TIMEOUT);
656 exit (1);
659 if (!seen_driver) {
660 usage (stderr);
661 exit (1);
664 drivers = jack_drivers_load ();
665 if (!drivers) {
666 fprintf (stderr, "jackd: no drivers found; exiting\n");
667 exit (1);
670 desc = jack_find_driver_descriptor (driver_name);
671 if (!desc) {
672 fprintf (stderr, "jackd: unknown driver '%s'\n", driver_name);
673 exit (1);
676 if (optind < argc) {
677 driver_nargs = 1 + argc - optind;
678 } else {
679 driver_nargs = 1;
682 if (driver_nargs == 0) {
683 fprintf (stderr, "No driver specified ... hmm. JACK won't do"
684 " anything when run like this.\n");
685 return -1;
688 driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
689 driver_args[0] = driver_name;
691 for (i = 1; i < driver_nargs; i++) {
692 driver_args[i] = argv[optind++];
695 if (jack_parse_driver_params (desc, driver_nargs,
696 driver_args, &driver_params)) {
697 exit (0);
700 if (server_name == NULL)
701 server_name = jack_default_server_name ();
703 copyright (stdout);
705 rc = jack_register_server (server_name, replace_registry);
706 switch (rc) {
707 case EEXIST:
708 fprintf (stderr, "`%s' server already active\n", server_name);
709 exit (1);
710 case ENOSPC:
711 fprintf (stderr, "too many servers already active\n");
712 exit (2);
713 case ENOMEM:
714 fprintf (stderr, "no access to shm registry\n");
715 exit (3);
716 default:
717 if (verbose)
718 fprintf (stderr, "server `%s' registered\n",
719 server_name);
722 /* clean up shared memory and files from any previous
723 * instance of this server name */
724 jack_cleanup_shm ();
725 jack_cleanup_files (server_name);
727 /* run the server engine until it terminates */
728 jack_main (desc, driver_params);
730 /* clean up shared memory and files from this server instance */
731 if (verbose)
732 fprintf (stderr, "cleaning up shared memory\n");
733 jack_cleanup_shm ();
734 if (verbose)
735 fprintf (stderr, "cleaning up files\n");
736 jack_cleanup_files (server_name);
737 if (verbose)
738 fprintf (stderr, "unregistering server `%s'\n", server_name);
739 jack_unregister_server (server_name);
741 exit (0);