remove unnecessary messing with signals from netjack_poll_deadline
[jack.git] / libjack / client.c
blobb57980a26398827b899db98f9d0ecc8a6ddbb814
1 /* -*- mode: c; c-file-style: "bsd"; -*- */
2 /*
3 Copyright (C) 2001-2003 Paul Davis
4 Copyright (C) 2005 Jussi Laako
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <config.h>
24 #include <pthread.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <limits.h>
30 #ifdef HAVE_STDINT_H
31 #include <stdint.h>
32 #endif
33 #include <regex.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <sys/mman.h>
40 #include <jack/internal.h>
41 #include <jack/jack.h>
42 #include <jack/engine.h>
43 #include <jack/pool.h>
44 #include <jack/jslist.h>
45 #include <jack/version.h>
46 #include <jack/shm.h>
47 #include <jack/unlock.h>
48 #include <jack/thread.h>
49 #include <jack/varargs.h>
50 #include <jack/intsimd.h>
52 #include <sysdeps/time.h>
54 #include "local.h"
56 #include <sysdeps/poll.h>
57 #include <sysdeps/ipc.h>
58 #include <sysdeps/cycles.h>
60 #ifdef JACK_USE_MACH_THREADS
61 #include <sysdeps/pThreadUtilities.h>
62 #endif
64 static pthread_mutex_t client_lock;
65 static pthread_cond_t client_ready;
67 static int
68 jack_client_close_aux (jack_client_t *client);
70 #define EVENT_POLL_INDEX 0
71 #define WAIT_POLL_INDEX 1
72 #define event_fd pollfd[EVENT_POLL_INDEX].fd
73 #define graph_wait_fd pollfd[WAIT_POLL_INDEX].fd
75 typedef struct {
76 int status;
77 struct _jack_client *client;
78 const char *client_name;
79 } client_info;
81 #ifdef USE_DYNSIMD
83 #ifdef ARCH_X86
85 int cpu_type = 0;
87 static void
88 init_cpu ()
90 cpu_type = ((have_3dnow() << 8) | have_sse());
91 if (ARCH_X86_HAVE_3DNOW(cpu_type))
92 jack_info("Enhanced3DNow! detected");
93 if (ARCH_X86_HAVE_SSE2(cpu_type))
94 jack_info("SSE2 detected");
95 if ((!ARCH_X86_HAVE_3DNOW(cpu_type)) && (!ARCH_X86_HAVE_SSE2(cpu_type)))
96 jack_info("No supported SIMD instruction sets detected");
97 jack_port_set_funcs();
100 #else /* ARCH_X86 */
102 static void
103 init_cpu ()
105 jack_port_set_funcs();
108 #endif /* ARCH_X86 */
110 #endif /* USE_DYNSIMD */
112 char *jack_tmpdir = DEFAULT_TMP_DIR;
114 static int
115 jack_get_tmpdir ()
117 FILE* in;
118 size_t len;
119 char buf[PATH_MAX+2]; /* allow tmpdir to live anywhere, plus newline, plus null */
120 char *pathenv;
121 char *pathcopy;
122 char *p;
124 /* some implementations of popen(3) close a security loophole by
125 resetting PATH for the exec'd command. since we *want* to
126 use the user's PATH setting to locate jackd, we have to
127 do it ourselves.
130 if ((pathenv = getenv ("PATH")) == 0) {
131 return -1;
134 /* don't let strtok(3) mess with the real environment variable */
136 pathcopy = strdup (pathenv);
137 p = strtok (pathcopy, ":");
139 while (p) {
140 char jackd[PATH_MAX+1];
141 char command[PATH_MAX+4];
143 snprintf (jackd, sizeof (jackd), "%s/jackd", p);
145 if (access (jackd, X_OK) == 0) {
147 snprintf (command, sizeof (command), "%s -l", jackd);
149 if ((in = popen (command, "r")) != NULL) {
150 break;
154 p = strtok (NULL, ":");
157 if (p == NULL) {
158 /* no command successfully started */
159 free (pathcopy);
160 return -1;
163 if (fgets (buf, sizeof (buf), in) == NULL) {
164 fclose (in);
165 free (pathcopy);
166 return -1;
169 len = strlen (buf);
171 if (buf[len-1] != '\n') {
172 /* didn't get a whole line */
173 fclose (in);
174 free (pathcopy);
175 return -1;
178 jack_tmpdir = (char *) malloc (len);
179 memcpy (jack_tmpdir, buf, len-1);
180 jack_tmpdir[len-1] = '\0';
182 fclose (in);
183 free (pathcopy);
184 return 0;
187 void
188 jack_error (const char *fmt, ...)
190 va_list ap;
191 char buffer[300];
193 va_start (ap, fmt);
194 vsnprintf (buffer, sizeof(buffer), fmt, ap);
195 jack_error_callback (buffer);
196 va_end (ap);
199 void
200 default_jack_error_callback (const char *desc)
202 #ifdef DEBUG_ENABLED
203 DEBUG("%s", desc);
204 #else
205 fprintf(stderr, "%s\n", desc);
206 fflush(stderr);
207 #endif
210 void
211 default_jack_info_callback (const char *desc)
213 fprintf(stdout, "%s\n", desc);
214 fflush(stdout);
217 void
218 silent_jack_error_callback (const char *desc)
222 void (*jack_error_callback)(const char *desc) = &default_jack_error_callback;
223 void (*jack_info_callback)(const char *desc) = &default_jack_info_callback;
225 void
226 jack_info (const char *fmt, ...)
228 va_list ap;
229 char buffer[300];
231 va_start (ap, fmt);
232 vsnprintf (buffer, sizeof(buffer), fmt, ap);
233 jack_info_callback (buffer);
234 va_end (ap);
237 static int
238 oop_client_deliver_request (void *ptr, jack_request_t *req)
240 int wok, rok;
241 jack_client_t *client = (jack_client_t*) ptr;
243 wok = (write (client->request_fd, req, sizeof (*req))
244 == sizeof (*req));
245 rok = (read (client->request_fd, req, sizeof (*req))
246 == sizeof (*req));
248 if (wok && rok) { /* everything OK? */
249 return req->status;
252 req->status = -1; /* request failed */
254 /* check for server shutdown */
255 if (client->engine->engine_ok == 0)
256 return req->status;
258 /* otherwise report errors */
259 if (!wok)
260 jack_error ("cannot send request type %d to server",
261 req->type);
262 if (!rok)
263 jack_error ("cannot read result for request type %d from"
264 " server (%s)", req->type, strerror (errno));
265 return req->status;
269 jack_client_deliver_request (const jack_client_t *client, jack_request_t *req)
271 /* indirect through the function pointer that was set either
272 * by jack_client_open() or by jack_new_client_request() in
273 * the server.
276 return client->deliver_request (client->deliver_arg,
277 req);
280 #if JACK_USE_MACH_THREADS
282 jack_client_t *
283 jack_client_alloc ()
285 jack_client_t *client;
287 client = (jack_client_t *) malloc (sizeof (jack_client_t));
288 client->pollfd = (struct pollfd *) malloc (sizeof (struct pollfd) * 1);
289 client->pollmax = 1;
290 client->request_fd = -1;
291 client->event_fd = -1;
292 client->upstream_is_jackd = 0;
293 client->graph_wait_fd = -1;
294 client->graph_next_fd = -1;
295 client->ports = NULL;
296 client->ports_ext = NULL;
297 client->engine = NULL;
298 client->control = NULL;
299 client->thread_ok = FALSE;
300 client->rt_thread_ok = FALSE;
301 client->first_active = TRUE;
302 client->on_shutdown = NULL;
303 client->on_info_shutdown = NULL;
304 client->n_port_types = 0;
305 client->port_segment = NULL;
307 #ifdef USE_DYNSIMD
308 init_cpu();
309 #endif /* USE_DYNSIMD */
311 return client;
314 #else
316 jack_client_t *
317 jack_client_alloc ()
319 jack_client_t *client;
321 client = (jack_client_t *) malloc (sizeof (jack_client_t));
322 client->pollfd = (struct pollfd *) malloc (sizeof (struct pollfd) * 2);
323 client->pollmax = 2;
324 client->request_fd = -1;
325 client->event_fd = -1;
326 client->upstream_is_jackd = 0;
327 client->graph_wait_fd = -1;
328 client->graph_next_fd = -1;
329 client->ports = NULL;
330 client->ports_ext = NULL;
331 client->engine = NULL;
332 client->control = NULL;
333 client->thread_ok = FALSE;
334 client->first_active = TRUE;
335 client->on_shutdown = NULL;
336 client->on_info_shutdown = NULL;
337 client->n_port_types = 0;
338 client->port_segment = NULL;
340 #ifdef USE_DYNSIMD
341 init_cpu();
342 #endif /* USE_DYNSIMD */
344 return client;
347 #endif
350 * Build the jack_client_t structure for an internal client.
352 jack_client_t *
353 jack_client_alloc_internal (jack_client_control_t *cc, jack_engine_t* engine)
355 jack_client_t* client;
357 client = jack_client_alloc ();
359 client->control = cc;
360 client->engine = engine->control;
362 client->n_port_types = client->engine->n_port_types;
363 client->port_segment = &engine->port_segment[0];
365 return client;
368 static void
369 jack_client_free (jack_client_t *client)
371 if (client->pollfd) {
372 free (client->pollfd);
375 free (client);
378 void
379 jack_client_invalidate_port_buffers (jack_client_t *client)
381 JSList *node;
382 jack_port_t *port;
384 /* This releases all local memory owned by input ports
385 and sets the buffer pointer to NULL. This will cause
386 jack_port_get_buffer() to reallocate space for the
387 buffer on the next call (if there is one).
390 for (node = client->ports; node; node = jack_slist_next (node)) {
391 port = (jack_port_t *) node->data;
393 if (port->shared->flags & JackPortIsInput) {
394 if (port->mix_buffer) {
395 jack_pool_release (port->mix_buffer);
396 port->mix_buffer = NULL;
403 jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)
405 jack_port_t *control_port;
406 jack_port_t *other = 0;
407 JSList *node;
408 int need_free = FALSE;
410 if (client->engine->ports[event->x.self_id].client_id == client->control->id ||
411 client->engine->ports[event->y.other_id].client_id == client->control->id) {
413 /* its one of ours */
415 switch (event->type) {
416 case PortConnected:
417 other = jack_port_new (client, event->y.other_id,
418 client->engine);
419 /* jack_port_by_id_int() always returns an internal
420 * port that does not need to be deallocated
422 control_port = jack_port_by_id_int (client, event->x.self_id,
423 &need_free);
424 pthread_mutex_lock (&control_port->connection_lock);
425 control_port->connections =
426 jack_slist_prepend (control_port->connections,
427 (void *) other);
428 pthread_mutex_unlock (&control_port->connection_lock);
429 break;
431 case PortDisconnected:
432 /* jack_port_by_id_int() always returns an internal
433 * port that does not need to be deallocated
435 control_port = jack_port_by_id_int (client, event->x.self_id,
436 &need_free);
437 pthread_mutex_lock (&control_port->connection_lock);
439 for (node = control_port->connections; node;
440 node = jack_slist_next (node)) {
442 other = (jack_port_t *) node->data;
444 if (other->shared->id == event->y.other_id) {
445 control_port->connections =
446 jack_slist_remove_link (
447 control_port->connections,
448 node);
449 jack_slist_free_1 (node);
450 free (other);
451 break;
455 pthread_mutex_unlock (&control_port->connection_lock);
456 break;
458 default:
459 /* impossible */
460 break;
464 if (client->control->port_connect_cbset) {
465 client->port_connect (event->x.self_id, event->y.other_id,
466 (event->type == PortConnected ? 1 : 0),
467 client->port_connect_arg);
470 return 0;
473 #if JACK_USE_MACH_THREADS
475 static int
476 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
478 client->pollmax = 1;
480 /* If the client registered its own callback for graph order events,
481 execute it now.
484 if (client->control->graph_order_cbset) {
485 client->graph_order (client->graph_order_arg);
488 return 0;
491 #else
493 static int
494 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
496 char path[PATH_MAX+1];
498 DEBUG ("graph reorder\n");
500 if (client->graph_wait_fd >= 0) {
501 DEBUG ("closing graph_wait_fd==%d", client->graph_wait_fd);
502 close (client->graph_wait_fd);
503 client->graph_wait_fd = -1;
506 if (client->graph_next_fd >= 0) {
507 DEBUG ("closing graph_next_fd==%d", client->graph_next_fd);
508 close (client->graph_next_fd);
509 client->graph_next_fd = -1;
512 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n);
514 if ((client->graph_wait_fd = open (path, O_RDONLY|O_NONBLOCK)) < 0) {
515 jack_error ("cannot open specified fifo [%s] for reading (%s)",
516 path, strerror (errno));
517 return -1;
519 DEBUG ("opened new graph_wait_fd %d (%s)", client->graph_wait_fd, path);
521 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n+1);
523 if ((client->graph_next_fd = open (path, O_WRONLY|O_NONBLOCK)) < 0) {
524 jack_error ("cannot open specified fifo [%s] for writing (%s)",
525 path, strerror (errno));
526 return -1;
529 client->upstream_is_jackd = event->y.n;
530 client->pollmax = 2;
532 DEBUG ("opened new graph_next_fd %d (%s) (upstream is jackd? %d)",
533 client->graph_next_fd, path,
534 client->upstream_is_jackd);
536 /* If the client registered its own callback for graph order events,
537 execute it now.
540 if (client->control->graph_order_cbset) {
541 client->graph_order (client->graph_order_arg);
544 return 0;
547 #endif
549 static int
550 server_connect (const char *server_name)
552 int fd;
553 struct sockaddr_un addr;
554 int which = 0;
556 char server_dir[PATH_MAX+1] = "";
558 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
559 jack_error ("cannot create client socket (%s)",
560 strerror (errno));
561 return -1;
564 //JOQ: temporary debug message
565 //jack_info ("DEBUG: connecting to `%s' server", server_name);
567 addr.sun_family = AF_UNIX;
568 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_%d",
569 jack_server_dir (server_name, server_dir) , which);
571 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
572 close (fd);
573 return -1;
576 return fd;
579 static int
580 server_event_connect (jack_client_t *client, const char *server_name)
582 int fd;
583 struct sockaddr_un addr;
584 jack_client_connect_ack_request_t req;
585 jack_client_connect_ack_result_t res;
587 char server_dir[PATH_MAX+1] = "";
589 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
590 jack_error ("cannot create client event socket (%s)",
591 strerror (errno));
592 return -1;
595 addr.sun_family = AF_UNIX;
596 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_ack_0",
597 jack_server_dir (server_name,server_dir));
599 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
600 jack_error ("cannot connect to jack server for events",
601 strerror (errno));
602 close (fd);
603 return -1;
606 req.client_id = client->control->id;
608 if (write (fd, &req, sizeof (req)) != sizeof (req)) {
609 jack_error ("cannot write event connect request to server (%s)",
610 strerror (errno));
611 close (fd);
612 return -1;
615 if (read (fd, &res, sizeof (res)) != sizeof (res)) {
616 jack_error ("cannot read event connect result from server (%s)",
617 strerror (errno));
618 close (fd);
619 return -1;
622 if (res.status != 0) {
623 jack_error ("cannot connect to server for event stream (%s)",
624 strerror (errno));
625 close (fd);
626 return -1;
629 return fd;
632 /* Exec the JACK server in this process. Does not return. */
633 static void
634 _start_server (const char *server_name)
636 FILE* fp = 0;
637 char filename[255];
638 char arguments[255];
639 char buffer[255];
640 char* command = 0;
641 size_t pos = 0;
642 size_t result = 0;
643 char** argv = 0;
644 int i = 0;
645 int good = 0;
646 int ret;
648 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
649 fp = fopen(filename, "r");
651 if (!fp) {
652 fp = fopen("/etc/jackdrc", "r");
654 /* if still not found, check old config name for backwards compatability */
655 if (!fp) {
656 fp = fopen("/etc/jackd.conf", "r");
659 if (fp) {
660 arguments[0] = '\0';
661 ret = fscanf(fp, "%s", buffer);
662 while(ret != 0 && ret != EOF) {
663 strcat(arguments, buffer);
664 strcat(arguments, " ");
665 ret = fscanf(fp, "%s", buffer);
667 if (strlen(arguments) > 0) {
668 good = 1;
672 if (!good) {
673 #if defined(USE_CAPABILITIES)
674 command = JACK_LOCATION "/jackstart";
675 strncpy(arguments, JACK_LOCATION "/jackstart -T -R -d "
676 JACK_DEFAULT_DRIVER " -p 512", 255);
677 #else /* !USE_CAPABILITIES */
678 command = JACK_LOCATION "/jackd";
679 strncpy(arguments, JACK_LOCATION "/jackd -T -d "
680 JACK_DEFAULT_DRIVER, 255);
681 #endif /* USE_CAPABILITIES */
682 } else {
683 result = strcspn(arguments, " ");
684 command = (char *) malloc(result+1);
685 strncpy(command, arguments, result);
686 command[result] = '\0';
689 argv = (char **) malloc (255);
691 while(1) {
692 /* insert -T and -nserver_name in front of arguments */
693 if (i == 1) {
694 argv[i] = (char *) malloc(strlen ("-T") + 1);
695 strcpy (argv[i++], "-T");
696 if (server_name) {
697 size_t optlen = strlen ("-n");
698 char *buf =
699 malloc (optlen
700 + strlen (server_name) + 1);
701 strcpy (buf, "-n");
702 strcpy (buf+optlen, server_name);
703 argv[i++] = buf;
707 result = strcspn(arguments+pos, " ");
708 if (result == 0) {
709 break;
711 argv[i] = (char*)malloc(result+1);
713 strncpy(argv[i], arguments+pos, result);
714 argv[i][result] = '\0';
716 pos += result+1;
717 ++i;
719 argv[i] = 0;
721 #if 0
722 fprintf (stderr, "execing JACK using %s\n", command);
723 for (_xx = 0; argv[_xx]; ++_xx) {
724 fprintf (stderr, "\targv[%d] = %s\n", _xx, argv[_xx]);
726 #endif
728 execv (command, argv);
730 /* If execv() succeeds, it does not return. There's no point
731 * in calling jack_error() here in the child process. */
732 fprintf (stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror (errno));
736 start_server (const char *server_name, jack_options_t options)
738 if ((options & JackNoStartServer)
739 || getenv("JACK_NO_START_SERVER")) {
740 return 1;
743 /* The double fork() forces the server to become a child of
744 * init, which will always clean up zombie process state on
745 * termination. This even works in cases where the server
746 * terminates but this client does not.
748 * Since fork() is usually implemented using copy-on-write
749 * virtual memory tricks, the overhead of the second fork() is
750 * probably relatively small.
752 switch (fork()) {
753 case 0: /* child process */
754 switch (fork()) {
755 case 0: /* grandchild process */
756 _start_server(server_name);
757 _exit (99); /* exec failed */
758 case -1:
759 _exit (98);
760 default:
761 _exit (0);
763 case -1: /* fork() error */
764 return 1; /* failed to start server */
767 /* only the original parent process goes here */
768 return 0; /* (probably) successful */
771 static int
772 jack_request_client (ClientType type,
773 const char* client_name, jack_options_t options,
774 jack_status_t *status, jack_varargs_t *va,
775 jack_client_connect_result_t *res, int *req_fd)
777 jack_client_connect_request_t req;
779 *req_fd = -1;
780 memset (&req, 0, sizeof (req));
781 req.options = options;
783 if (strlen (client_name) >= sizeof (req.name)) {
784 jack_error ("\"%s\" is too long to be used as a JACK client"
785 " name.\n"
786 "Please use %lu characters or less.",
787 client_name, sizeof (req.name));
788 return -1;
791 if (va->load_name
792 && (strlen (va->load_name) > sizeof (req.object_path) - 1)) {
793 jack_error ("\"%s\" is too long to be used as a JACK shared"
794 " object name.\n"
795 "Please use %lu characters or less.",
796 va->load_name, sizeof (req.object_path) - 1);
797 return -1;
800 if (va->load_init
801 && (strlen (va->load_init) > sizeof (req.object_data) - 1)) {
802 jack_error ("\"%s\" is too long to be used as a JACK shared"
803 " object data string.\n"
804 "Please use %lu characters or less.",
805 va->load_init, sizeof (req.object_data) - 1);
806 return -1;
809 if ((*req_fd = server_connect (va->server_name)) < 0) {
810 int trys;
811 if (start_server(va->server_name, options)) {
812 *status |= (JackFailure|JackServerFailed);
813 goto fail;
815 trys = 5;
816 do {
817 sleep(1);
818 if (--trys < 0) {
819 *status |= (JackFailure|JackServerFailed);
820 goto fail;
822 } while ((*req_fd = server_connect (va->server_name)) < 0);
823 *status |= JackServerStarted;
826 /* format connection request */
828 req.protocol_v = jack_protocol_version;
829 req.load = TRUE;
830 req.type = type;
831 snprintf (req.name, sizeof (req.name),
832 "%s", client_name);
833 snprintf (req.object_path, sizeof (req.object_path),
834 "%s", va->load_name);
835 snprintf (req.object_data, sizeof (req.object_data),
836 "%s", va->load_init);
838 if (write (*req_fd, &req, sizeof (req)) != sizeof (req)) {
839 jack_error ("cannot send request to jack server (%s)",
840 strerror (errno));
841 *status |= (JackFailure|JackServerError);
842 goto fail;
845 if (read (*req_fd, res, sizeof (*res)) != sizeof (*res)) {
847 if (errno == 0) {
848 /* server shut the socket */
849 jack_error ("could not attach as client");
850 *status |= (JackFailure|JackServerError);
851 goto fail;
854 if (errno == ECONNRESET) {
855 jack_error ("could not attach as JACK client "
856 "(server has exited)");
857 *status |= (JackFailure|JackServerError);
858 goto fail;
861 jack_error ("cannot read response from jack server (%s)",
862 strerror (errno));
863 *status |= (JackFailure|JackServerError);
864 goto fail;
867 *status |= res->status; /* return server status bits */
869 if (*status & JackFailure) {
870 if (*status & JackVersionError) {
871 jack_error ("client linked with incompatible libjack"
872 " version.");
874 jack_error ("could not attach to JACK server");
875 *status |= JackServerError;
876 goto fail;
879 switch (type) {
880 case ClientDriver:
881 case ClientInternal:
882 close (*req_fd);
883 *req_fd = -1;
884 break;
886 default:
887 break;
890 return 0;
892 fail:
893 if (*req_fd >= 0) {
894 close (*req_fd);
895 *req_fd = -1;
897 return -1;
901 jack_attach_port_segment (jack_client_t *client, jack_port_type_id_t ptid)
903 /* Lookup, attach and register the port/buffer segments in use
904 * right now.
907 if (client->control->type != ClientExternal) {
908 jack_error("Only external clients need attach port segments");
909 abort();
912 /* make sure we have space to store the port
913 segment information.
916 if (ptid >= client->n_port_types) {
918 client->port_segment = (jack_shm_info_t*)
919 realloc (client->port_segment,
920 sizeof (jack_shm_info_t) * (ptid+1));
922 memset (&client->port_segment[client->n_port_types],
924 sizeof (jack_shm_info_t) *
925 (ptid - client->n_port_types));
927 client->n_port_types = ptid + 1;
929 } else {
931 /* release any previous segment */
932 jack_release_shm (&client->port_segment[ptid]);
935 /* get the index into the shm registry */
937 client->port_segment[ptid].index =
938 client->engine->port_types[ptid].shm_registry_index;
940 /* attach the relevant segment */
942 if (jack_attach_shm (&client->port_segment[ptid])) {
943 jack_error ("cannot attach port segment shared memory"
944 " (%s)", strerror (errno));
945 return -1;
948 return 0;
951 jack_client_t *
952 jack_client_open_aux (const char *client_name,
953 jack_options_t options,
954 jack_status_t *status, va_list ap)
956 /* optional arguments: */
957 jack_varargs_t va; /* variable arguments */
959 int req_fd = -1;
960 int ev_fd = -1;
961 jack_client_connect_result_t res;
962 jack_client_t *client;
963 jack_port_type_id_t ptid;
964 jack_status_t my_status;
966 jack_messagebuffer_init ();
968 if (status == NULL) /* no status from caller? */
969 status = &my_status; /* use local status word */
970 *status = 0;
972 /* validate parameters */
973 if ((options & ~JackOpenOptions)) {
974 *status |= (JackFailure|JackInvalidOption);
975 jack_messagebuffer_exit ();
976 return NULL;
979 /* parse variable arguments */
980 jack_varargs_parse(options, ap, &va);
982 /* External clients need to know where the tmpdir used for
983 communication with the server lives
985 if (jack_get_tmpdir ()) {
986 *status |= JackFailure;
987 jack_messagebuffer_exit ();
988 return NULL;
991 /* External clients need this initialized. It is already set
992 * up in the server's address space for internal clients.
994 jack_init_time ();
996 if (jack_request_client (ClientExternal, client_name, options, status,
997 &va, &res, &req_fd)) {
998 jack_messagebuffer_exit ();
999 return NULL;
1002 /* Allocate the jack_client_t structure in local memory.
1003 * Shared memory is not accessible yet. */
1004 client = jack_client_alloc ();
1005 strcpy (client->name, res.name);
1006 strcpy (client->fifo_prefix, res.fifo_prefix);
1007 client->request_fd = req_fd;
1008 client->pollfd[EVENT_POLL_INDEX].events =
1009 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1010 #ifndef JACK_USE_MACH_THREADS
1011 client->pollfd[WAIT_POLL_INDEX].events =
1012 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1013 #endif
1015 /* Don't access shared memory until server connected. */
1016 if (jack_initialize_shm (va.server_name)) {
1017 jack_error ("Unable to initialize shared memory.");
1018 *status |= (JackFailure|JackShmFailure);
1019 goto fail;
1022 /* attach the engine control/info block */
1023 client->engine_shm.index = res.engine_shm_index;
1024 if (jack_attach_shm (&client->engine_shm)) {
1025 jack_error ("cannot attached engine control shared memory"
1026 " segment");
1027 goto fail;
1030 client->engine = (jack_control_t *) jack_shm_addr (&client->engine_shm);
1032 /* initialize clock source as early as possible */
1033 jack_set_clock_source (client->engine->clock_source);
1035 /* now attach the client control block */
1036 client->control_shm.index = res.client_shm_index;
1037 if (jack_attach_shm (&client->control_shm)) {
1038 jack_error ("cannot attached client control shared memory"
1039 " segment");
1040 goto fail;
1043 client->control = (jack_client_control_t *)
1044 jack_shm_addr (&client->control_shm);
1046 /* Nobody else needs to access this shared memory any more, so
1047 * destroy it. Because we have it attached, it won't vanish
1048 * till we exit (and release it).
1050 jack_destroy_shm (&client->control_shm);
1052 client->n_port_types = client->engine->n_port_types;
1053 client->port_segment = (jack_shm_info_t *)
1054 malloc (sizeof (jack_shm_info_t) * client->n_port_types);
1056 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
1057 client->port_segment[ptid].index =
1058 client->engine->port_types[ptid].shm_registry_index;
1059 client->port_segment[ptid].attached_at = MAP_FAILED;
1060 jack_attach_port_segment (client, ptid);
1063 /* set up the client so that it does the right thing for an
1064 * external client
1066 client->deliver_request = oop_client_deliver_request;
1067 client->deliver_arg = client;
1069 if ((ev_fd = server_event_connect (client, va.server_name)) < 0) {
1070 goto fail;
1073 client->event_fd = ev_fd;
1075 #ifdef JACK_USE_MACH_THREADS
1076 /* specific resources for server/client real-time thread
1077 * communication */
1078 client->clienttask = mach_task_self();
1080 if (task_get_bootstrap_port(client->clienttask, &client->bp)){
1081 jack_error ("Can't find bootstrap port");
1082 goto fail;
1085 if (allocate_mach_clientport(client, res.portnum) < 0) {
1086 jack_error("Can't allocate mach port");
1087 goto fail;
1089 #endif /* JACK_USE_MACH_THREADS */
1090 return client;
1092 fail:
1093 jack_messagebuffer_exit ();
1095 if (client->engine) {
1096 jack_release_shm (&client->engine_shm);
1097 client->engine = 0;
1099 if (client->control) {
1100 jack_release_shm (&client->control_shm);
1101 client->control = 0;
1103 if (req_fd >= 0) {
1104 close (req_fd);
1106 if (ev_fd >= 0) {
1107 close (ev_fd);
1109 free (client);
1111 return NULL;
1114 jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
1116 va_list ap;
1117 va_start(ap, status);
1118 jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
1119 va_end(ap);
1120 return res;
1123 jack_client_t *
1124 jack_client_new (const char *client_name)
1126 jack_options_t options = JackUseExactName;
1127 if (getenv("JACK_START_SERVER") == NULL)
1128 options |= JackNoStartServer;
1129 return jack_client_open (client_name, options, NULL);
1132 char *
1133 jack_get_client_name (jack_client_t *client)
1135 return client->name;
1139 jack_internal_client_new (const char *client_name,
1140 const char *so_name, const char *so_data)
1142 jack_client_connect_result_t res;
1143 int req_fd;
1144 jack_varargs_t va;
1145 jack_status_t status;
1146 jack_options_t options = JackUseExactName;
1148 if (getenv("JACK_START_SERVER") == NULL)
1149 options |= JackNoStartServer;
1151 jack_varargs_init (&va);
1152 va.load_name = (char *) so_name;
1153 va.load_init = (char *) so_data;
1155 return jack_request_client (ClientInternal, client_name,
1156 options, &status, &va, &res, &req_fd);
1159 char *
1160 jack_default_server_name (void)
1162 char *server_name;
1163 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
1164 server_name = "default";
1165 return server_name;
1168 /* returns the name of the per-user subdirectory of jack_tmpdir */
1169 char *
1170 jack_user_dir (void)
1172 static char user_dir[PATH_MAX+1] = "";
1174 /* format the path name on the first call */
1175 if (user_dir[0] == '\0') {
1176 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
1177 snprintf (user_dir, sizeof (user_dir), "%s/jack",
1178 jack_tmpdir);
1179 } else {
1180 snprintf (user_dir, sizeof (user_dir), "%s/jack-%d",
1181 jack_tmpdir, getuid ());
1185 return user_dir;
1188 /* returns the name of the per-server subdirectory of jack_user_dir() */
1189 char *
1190 jack_server_dir (const char *server_name, char *server_dir)
1192 /* format the path name into the suppled server_dir char array,
1193 * assuming that server_dir is at least as large as PATH_MAX+1 */
1195 snprintf (server_dir, PATH_MAX+1, "%s/%s",
1196 jack_user_dir (), server_name);
1198 return server_dir;
1201 void
1202 jack_internal_client_close (const char *client_name)
1204 jack_client_connect_request_t req;
1205 int fd;
1206 char *server_name = jack_default_server_name ();
1208 req.load = FALSE;
1209 snprintf (req.name, sizeof (req.name), "%s", client_name);
1211 if ((fd = server_connect (server_name)) < 0) {
1212 return;
1215 if (write (fd, &req, sizeof (req)) != sizeof(req)) {
1216 jack_error ("cannot deliver ClientUnload request to JACK "
1217 "server.");
1220 /* no response to this request */
1222 close (fd);
1223 return;
1227 jack_recompute_total_latencies (jack_client_t* client)
1229 jack_request_t request;
1231 request.type = RecomputeTotalLatencies;
1232 return jack_client_deliver_request (client, &request);
1236 jack_recompute_total_latency (jack_client_t* client, jack_port_t* port)
1238 jack_request_t request;
1240 request.type = RecomputeTotalLatency;
1241 request.x.port_info.port_id = port->shared->id;
1242 return jack_client_deliver_request (client, &request);
1246 jack_set_freewheel (jack_client_t* client, int onoff)
1248 jack_request_t request;
1250 request.type = onoff ? FreeWheel : StopFreeWheel;
1251 return jack_client_deliver_request (client, &request);
1254 void
1255 jack_start_freewheel (jack_client_t* client)
1257 jack_client_control_t *control = client->control;
1259 if (client->engine->real_time) {
1260 #if JACK_USE_MACH_THREADS
1261 jack_drop_real_time_scheduling (client->process_thread);
1262 #else
1263 jack_drop_real_time_scheduling (client->thread);
1264 #endif
1267 if (control->freewheel_cb_cbset) {
1268 client->freewheel_cb (1, client->freewheel_arg);
1272 void
1273 jack_stop_freewheel (jack_client_t* client)
1275 jack_client_control_t *control = client->control;
1277 if (client->engine->real_time) {
1278 #if JACK_USE_MACH_THREADS
1279 jack_acquire_real_time_scheduling (client->process_thread,
1280 client->engine->client_priority);
1281 #else
1282 jack_acquire_real_time_scheduling (client->thread,
1283 client->engine->client_priority);
1284 #endif
1287 if (control->freewheel_cb_cbset) {
1288 client->freewheel_cb (0, client->freewheel_arg);
1292 static void
1293 jack_client_thread_suicide (jack_client_t* client)
1295 if (client->on_info_shutdown) {
1296 jack_error ("zombified - calling shutdown handler");
1297 client->on_info_shutdown (JackClientZombie, "Zombified", client->on_info_shutdown_arg);
1298 } else if (client->on_shutdown) {
1299 jack_error ("zombified - calling shutdown handler");
1300 client->on_shutdown (client->on_shutdown_arg);
1301 } else {
1302 jack_error ("jack_client_thread zombified - exiting from JACK");
1303 jack_client_close_aux (client);
1304 /* Need a fix : possibly make client crash if
1305 * zombified without shutdown handler
1309 pthread_exit (0);
1310 /*NOTREACHED*/
1313 static int
1314 jack_client_process_events (jack_client_t* client)
1316 jack_event_t event;
1317 char status = 0;
1318 jack_client_control_t *control = client->control;
1319 JSList *node;
1320 jack_port_t* port;
1322 DEBUG ("process events");
1324 if (client->pollfd[EVENT_POLL_INDEX].revents & POLLIN) {
1326 DEBUG ("client receives an event, "
1327 "now reading on event fd");
1329 /* server has sent us an event. process the
1330 * event and reply */
1332 if (read (client->event_fd, &event, sizeof (event))
1333 != sizeof (event)) {
1334 jack_error ("cannot read server event (%s)",
1335 strerror (errno));
1336 return -1;
1339 status = 0;
1341 switch (event.type) {
1342 case PortRegistered:
1343 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
1344 port = node->data;
1345 if (port->shared->id == event.x.port_id) { // Found port, update port type
1346 port->type_info = &client->engine->port_types[port->shared->ptype_id];
1349 if (control->port_register_cbset) {
1350 client->port_register
1351 (event.x.port_id, TRUE,
1352 client->port_register_arg);
1354 break;
1356 case PortUnregistered:
1357 if (control->port_register_cbset) {
1358 client->port_register
1359 (event.x.port_id, FALSE,
1360 client->port_register_arg);
1362 break;
1364 case ClientRegistered:
1365 if (control->client_register_cbset) {
1366 client->client_register
1367 (event.x.name, TRUE,
1368 client->client_register_arg);
1370 break;
1372 case ClientUnregistered:
1373 if (control->client_register_cbset) {
1374 client->client_register
1375 (event.x.name, FALSE,
1376 client->client_register_arg);
1378 break;
1380 case GraphReordered:
1381 status = jack_handle_reorder (client, &event);
1382 break;
1384 case PortConnected:
1385 case PortDisconnected:
1386 status = jack_client_handle_port_connection
1387 (client, &event);
1388 break;
1390 case BufferSizeChange:
1391 jack_client_invalidate_port_buffers (client);
1392 if (control->bufsize_cbset) {
1393 status = client->bufsize
1394 (control->nframes,
1395 client->bufsize_arg);
1397 break;
1399 case SampleRateChange:
1400 if (control->srate_cbset) {
1401 status = client->srate
1402 (control->nframes,
1403 client->srate_arg);
1405 break;
1407 case XRun:
1408 if (control->xrun_cbset) {
1409 status = client->xrun
1410 (client->xrun_arg);
1412 break;
1414 case AttachPortSegment:
1415 jack_attach_port_segment (client, event.y.ptid);
1416 break;
1418 case StartFreewheel:
1419 jack_start_freewheel (client);
1420 break;
1422 case StopFreewheel:
1423 jack_stop_freewheel (client);
1424 break;
1427 DEBUG ("client has dealt with the event, writing "
1428 "response on event fd");
1430 if (write (client->event_fd, &status, sizeof (status))
1431 != sizeof (status)) {
1432 jack_error ("cannot send event response to "
1433 "engine (%s)", strerror (errno));
1434 return -1;
1438 return 0;
1441 static int
1442 jack_client_core_wait (jack_client_t* client)
1444 jack_client_control_t *control = client->control;
1446 DEBUG ("client polling on %s", client->pollmax == 2 ? x
1447 "event_fd and graph_wait_fd..." :
1448 "event_fd only");
1450 while (1) {
1451 if (poll (client->pollfd, client->pollmax, 1000) < 0) {
1452 if (errno == EINTR) {
1453 continue;
1455 jack_error ("poll failed in client (%s)",
1456 strerror (errno));
1457 return -1;
1460 pthread_testcancel();
1462 #ifndef JACK_USE_MACH_THREADS
1464 /* get an accurate timestamp on waking from poll for a
1465 * process() cycle.
1468 if (client->graph_wait_fd >= 0
1469 && client->pollfd[WAIT_POLL_INDEX].revents & POLLIN) {
1470 control->awake_at = jack_get_microseconds();
1473 DEBUG ("pfd[EVENT].revents = 0x%x pfd[WAIT].revents = 0x%x",
1474 client->pollfd[EVENT_POLL_INDEX].revents,
1475 client->pollfd[WAIT_POLL_INDEX].revents);
1477 if (client->graph_wait_fd >= 0 &&
1478 (client->pollfd[WAIT_POLL_INDEX].revents & ~POLLIN)) {
1480 /* our upstream "wait" connection
1481 closed, which either means that
1482 an intermediate client exited, or
1483 jackd exited, or jackd zombified
1486 we can discover the zombification
1487 via client->control->dead, but
1488 the other two possibilities are
1489 impossible to identify just from
1490 this situation. so we have to
1491 check what we are connected to,
1492 and act accordingly.
1495 if (client->upstream_is_jackd) {
1496 DEBUG ("WE DIE\n");
1497 return 0;
1498 } else {
1499 DEBUG ("WE PUNT\n");
1500 /* don't poll on the wait fd
1501 * again until we get a
1502 * GraphReordered event.
1505 client->graph_wait_fd = -1;
1506 client->pollmax = 1;
1509 #endif
1511 if (jack_client_process_events (client)) {
1512 DEBUG ("event processing failed\n");
1513 return 0;
1516 if (client->graph_wait_fd >= 0 &&
1517 (client->pollfd[WAIT_POLL_INDEX].revents & POLLIN)) {
1518 DEBUG ("time to run process()\n");
1519 break;
1523 if (control->dead || client->pollfd[EVENT_POLL_INDEX].revents & ~POLLIN) {
1524 DEBUG ("client appears dead or event pollfd has error status\n");
1525 return -1;
1528 return 0;
1531 static int
1532 jack_wake_next_client (jack_client_t* client)
1534 struct pollfd pfds[1];
1535 int pret = 0;
1536 char c = 0;
1538 if (write (client->graph_next_fd, &c, sizeof (c))
1539 != sizeof (c)) {
1540 DEBUG("cannot write byte to fd %d", client->graph_next_fd);
1541 jack_error ("cannot continue execution of the "
1542 "processing graph (%s)",
1543 strerror(errno));
1544 return -1;
1547 DEBUG ("client sent message to next stage by %" PRIu64 "",
1548 jack_get_microseconds());
1550 DEBUG("reading cleanup byte from pipe %d\n", client->graph_wait_fd);
1552 /* "upstream client went away? readability is checked in
1553 * jack_client_core_wait(), but that's almost a whole cycle
1554 * before we get here.
1557 if (client->graph_wait_fd >= 0) {
1558 pfds[0].fd = client->graph_wait_fd;
1559 pfds[0].events = POLLIN;
1561 /* 0 timeout, don't actually wait */
1562 pret = poll(pfds, 1, 0);
1565 if (pret > 0 && (pfds[0].revents & POLLIN)) {
1566 if (read (client->graph_wait_fd, &c, sizeof (c))
1567 != sizeof (c)) {
1568 jack_error ("cannot complete execution of the "
1569 "processing graph (%s)", strerror(errno));
1570 return -1;
1572 } else {
1573 DEBUG("cleanup byte from pipe %d not available?\n",
1574 client->graph_wait_fd);
1577 return 0;
1580 static jack_nframes_t
1581 jack_thread_first_wait (jack_client_t* client)
1583 if (jack_client_core_wait (client)) {
1584 return 0;
1586 return client->control->nframes;
1589 jack_nframes_t
1590 jack_thread_wait (jack_client_t* client, int status)
1592 client->control->last_status = status;
1594 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1596 /* housekeeping/cleanup after data processing */
1598 if (status == 0 && client->control->timebase_cb_cbset) {
1599 jack_call_timebase_master (client);
1602 /* end preemption checking */
1603 CHECK_PREEMPTION (client->engine, FALSE);
1605 client->control->finished_at = jack_get_microseconds();
1607 /* wake the next client in the chain (could be the server),
1608 and check if we were killed during the process
1609 cycle.
1612 if (jack_wake_next_client (client)) {
1613 DEBUG("client cannot wake next, or is dead\n");
1614 return 0;
1617 if (status || client->control->dead || !client->engine->engine_ok) {
1618 return 0;
1621 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1623 if (jack_client_core_wait (client)) {
1624 return 0;
1627 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1629 /* Time to do data processing */
1631 client->control->state = Running;
1633 /* begin preemption checking */
1634 CHECK_PREEMPTION (client->engine, TRUE);
1636 if (client->control->sync_cb_cbset)
1637 jack_call_sync_client (client);
1639 return client->control->nframes;
1642 jack_nframes_t jack_cycle_wait (jack_client_t* client)
1644 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1646 if (jack_client_core_wait (client)) {
1647 return 0;
1650 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1652 /* Time to do data processing */
1654 client->control->state = Running;
1656 /* begin preemption checking */
1657 CHECK_PREEMPTION (client->engine, TRUE);
1659 if (client->control->sync_cb_cbset)
1660 jack_call_sync_client (client);
1662 return client->control->nframes;
1665 void jack_cycle_signal(jack_client_t* client, int status)
1667 client->control->last_status = status;
1669 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1671 /* housekeeping/cleanup after data processing */
1673 if (status == 0 && client->control->timebase_cb_cbset) {
1674 jack_call_timebase_master (client);
1677 /* end preemption checking */
1678 CHECK_PREEMPTION (client->engine, FALSE);
1680 client->control->finished_at = jack_get_microseconds();
1682 /* wake the next client in the chain (could be the server),
1683 and check if we were killed during the process
1684 cycle.
1687 if (jack_wake_next_client (client)) {
1688 DEBUG("client cannot wake next, or is dead\n");
1689 jack_client_thread_suicide (client);
1690 /*NOTREACHED*/
1693 if (status || client->control->dead || !client->engine->engine_ok) {
1694 jack_client_thread_suicide (client);
1695 /*NOTREACHED*/
1699 static void
1700 jack_client_thread_aux (void *arg)
1702 jack_client_t *client = (jack_client_t *) arg;
1703 jack_client_control_t *control = client->control;
1705 pthread_mutex_lock (&client_lock);
1706 client->thread_ok = TRUE;
1707 client->thread_id = pthread_self();
1708 pthread_cond_signal (&client_ready);
1709 pthread_mutex_unlock (&client_lock);
1711 control->pid = getpid();
1712 control->pgrp = getpgrp();
1714 DEBUG ("client thread is now running");
1716 if (control->thread_init_cbset) {
1717 DEBUG ("calling client thread init callback");
1718 client->thread_init (client->thread_init_arg);
1721 /* wait for first wakeup from server */
1723 if (jack_thread_first_wait (client) == control->nframes) {
1725 /* now run till we're done */
1727 if (control->process_cbset) {
1729 /* run process callback, then wait... ad-infinitum */
1731 while (1) {
1732 DEBUG("client calls process()");
1733 int status = (client->process (control->nframes,
1734 client->process_arg) ==
1735 control->nframes);
1736 control->state = Finished;
1737 DEBUG("client leaves process(), re-enters wait");
1738 if (!jack_thread_wait (client, status)) {
1739 break;
1741 DEBUG("client done with wait");
1744 } else {
1745 /* no process handling but still need to process events */
1746 while (jack_thread_wait (client, 0) == control->nframes)
1751 jack_client_thread_suicide (client);
1754 static void *
1755 jack_client_thread (void *arg)
1757 jack_client_t *client = (jack_client_t *) arg;
1758 jack_client_control_t *control = client->control;
1760 if (client->control->thread_cb_cbset) {
1762 pthread_mutex_lock (&client_lock);
1763 client->thread_ok = TRUE;
1764 client->thread_id = pthread_self();
1765 pthread_cond_signal (&client_ready);
1766 pthread_mutex_unlock (&client_lock);
1768 control->pid = getpid();
1769 control->pgrp = getpgrp();
1771 client->thread_cb(client->thread_cb_arg);
1772 jack_client_thread_suicide(client);
1773 } else {
1774 jack_client_thread_aux(arg);
1777 /*NOTREACHED*/
1778 return (void *) 0;
1781 #ifdef JACK_USE_MACH_THREADS
1782 /* real-time thread : separated from the normal client thread, it will
1783 * communicate with the server using fast mach RPC mechanism */
1785 static void *
1786 jack_client_process_thread (void *arg)
1788 jack_client_t *client = (jack_client_t *) arg;
1789 jack_client_control_t *control = client->control;
1790 int err = 0;
1792 if (client->control->thread_init_cbset) {
1793 /* this means that the init callback will be called twice -taybin*/
1794 DEBUG ("calling client thread init callback");
1795 client->thread_init (client->thread_init_arg);
1798 client->control->pid = getpid();
1799 DEBUG ("client process thread is now running");
1801 client->rt_thread_ok = TRUE;
1803 while (err == 0) {
1805 if (jack_client_suspend(client) < 0) {
1806 jack_error ("jack_client_process_thread :resume error");
1807 goto zombie;
1810 control->awake_at = jack_get_microseconds();
1812 DEBUG ("client resumed");
1814 control->state = Running;
1816 if (control->sync_cb_cbset)
1817 jack_call_sync_client (client);
1819 if (control->process_cbset) {
1820 if (client->process (control->nframes,
1821 client->process_arg) == 0) {
1822 control->state = Finished;
1824 } else {
1825 control->state = Finished;
1828 if (control->timebase_cb_cbset)
1829 jack_call_timebase_master (client);
1831 control->finished_at = jack_get_microseconds();
1833 DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
1834 control->finished_at,
1835 ((float)(control->finished_at - control->awake_at)));
1837 /* check if we were killed during the process cycle
1838 * (or whatever) */
1840 if (client->control->dead) {
1841 jack_error ("jack_client_process_thread: "
1842 "client->control->dead");
1843 goto zombie;
1846 DEBUG("process cycle fully complete\n");
1850 return (void *) ((intptr_t)err);
1852 zombie:
1854 jack_error ("jack_client_process_thread : zombified");
1856 client->rt_thread_ok = FALSE;
1858 if (client->on_info_shutdown) {
1859 jack_error ("zombified - calling shutdown handler");
1860 client->on_info_shutdown (JackClientZombie, "Zombified", client->on_info_shutdown_arg);
1861 } else if (client->on_shutdown) {
1862 jack_error ("zombified - calling shutdown handler");
1863 client->on_shutdown (client->on_shutdown_arg);
1864 } else {
1865 jack_error ("jack_client_process_thread zombified - exiting from JACK");
1866 /* Need a fix : possibly make client crash if
1867 * zombified without shutdown handler */
1868 jack_client_close_aux (client);
1871 pthread_exit (0);
1872 /*NOTREACHED*/
1873 return 0;
1875 #endif /* JACK_USE_MACH_THREADS */
1877 static int
1878 jack_start_thread (jack_client_t *client)
1880 if (client->engine->real_time) {
1882 #ifdef USE_MLOCK
1883 if (client->engine->do_mlock
1884 && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) {
1885 jack_error ("cannot lock down memory for RT thread "
1886 "(%s)", strerror (errno));
1888 #ifdef ENSURE_MLOCK
1889 return -1;
1890 #endif /* ENSURE_MLOCK */
1893 if (client->engine->do_munlock) {
1894 cleanup_mlock ();
1896 #endif /* USE_MLOCK */
1899 #ifdef JACK_USE_MACH_THREADS
1900 /* Stephane Letz : letz@grame.fr
1901 On MacOSX, the normal thread does not need to be real-time.
1903 if (jack_client_create_thread (client,
1904 &client->thread,
1905 client->engine->client_priority,
1906 FALSE,
1907 jack_client_thread, client)) {
1908 return -1;
1910 #else
1911 if (jack_client_create_thread (client,
1912 &client->thread,
1913 client->engine->client_priority,
1914 client->engine->real_time,
1915 jack_client_thread, client)) {
1916 return -1;
1919 #endif
1921 #ifdef JACK_USE_MACH_THREADS
1923 /* a secondary thread that runs the process callback and uses
1924 ultra-fast Mach primitives for inter-thread signalling.
1926 XXX in a properly structured JACK, there would be no
1927 need for this, because we would have client wake up
1928 methods that encapsulated the underlying mechanism
1929 used.
1933 if (jack_client_create_thread(client,
1934 &client->process_thread,
1935 client->engine->client_priority,
1936 client->engine->real_time,
1937 jack_client_process_thread, client)) {
1938 return -1;
1940 #endif /* JACK_USE_MACH_THREADS */
1942 return 0;
1945 int
1946 jack_activate (jack_client_t *client)
1948 jack_request_t req;
1950 /* we need to scribble on our stack to ensure that its memory
1951 * pages are actually mapped (more important for mlockall(2)
1952 * usage in jack_start_thread())
1955 char buf[JACK_THREAD_STACK_TOUCH];
1956 int i;
1958 for (i = 0; i < JACK_THREAD_STACK_TOUCH; i++) {
1959 buf[i] = (char) (i & 0xff);
1962 if (client->control->type == ClientInternal ||
1963 client->control->type == ClientDriver) {
1964 goto startit;
1967 /* get the pid of the client process to pass it to engine */
1969 client->control->pid = getpid ();
1971 #ifdef USE_CAPABILITIES
1973 if (client->engine->has_capabilities != 0 &&
1974 client->control->pid != 0 && client->engine->real_time != 0) {
1976 /* we need to ask the engine for realtime capabilities
1977 before trying to start the realtime thread
1980 req.type = SetClientCapabilities;
1981 req.x.client_id = client->control->id;
1982 req.x.cap_pid = client->control->pid;
1984 jack_client_deliver_request (client, &req);
1986 if (req.status) {
1988 /* what to do? engine is running realtime, it
1989 is using capabilities and has them
1990 (otherwise we would not get an error
1991 return) but for some reason it could not
1992 give the client the required capabilities.
1993 For now, leave the client so that it
1994 still runs, albeit non-realtime.
1997 jack_error ("could not receive realtime capabilities, "
1998 "client will run non-realtime");
2001 #endif /* USE_CAPABILITIES */
2003 if (client->first_active) {
2005 pthread_mutex_init (&client_lock, NULL);
2006 pthread_cond_init (&client_ready, NULL);
2008 pthread_mutex_lock (&client_lock);
2010 if (jack_start_thread (client)) {
2011 pthread_mutex_unlock (&client_lock);
2012 return -1;
2015 pthread_cond_wait (&client_ready, &client_lock);
2016 pthread_mutex_unlock (&client_lock);
2018 if (!client->thread_ok) {
2019 jack_error ("could not start client thread");
2020 return -1;
2023 client->first_active = FALSE;
2026 startit:
2028 req.type = ActivateClient;
2029 req.x.client_id = client->control->id;
2031 return jack_client_deliver_request (client, &req);
2034 static int
2035 jack_deactivate_aux (jack_client_t *client)
2037 jack_request_t req;
2038 int rc = ESRCH; /* already shut down */
2040 if (client && client->control) { /* not shut down? */
2041 rc = 0;
2042 if (client->control->active) { /* still active? */
2043 req.type = DeactivateClient;
2044 req.x.client_id = client->control->id;
2045 rc = jack_client_deliver_request (client, &req);
2048 return rc;
2051 int
2052 jack_deactivate (jack_client_t *client)
2054 return jack_deactivate_aux(client);
2057 static int
2058 jack_client_close_aux (jack_client_t *client)
2060 JSList *node;
2061 void *status;
2062 int rc;
2064 rc = jack_deactivate_aux (client);
2065 if (rc == ESRCH) { /* already shut down? */
2066 return rc;
2069 if (client->control->type == ClientExternal) {
2071 #if JACK_USE_MACH_THREADS
2072 if (client->rt_thread_ok) {
2073 // MacOSX pthread_cancel not implemented in
2074 // Darwin 5.5, 6.4
2075 mach_port_t machThread =
2076 pthread_mach_thread_np (client->process_thread);
2077 thread_terminate (machThread);
2079 #endif
2081 /* stop the thread that communicates with the jack
2082 * server, only if it was actually running
2085 if (client->thread_ok){
2086 pthread_cancel (client->thread);
2087 pthread_join (client->thread, &status);
2090 if (client->control) {
2091 jack_release_shm (&client->control_shm);
2092 client->control = NULL;
2094 if (client->engine) {
2095 jack_release_shm (&client->engine_shm);
2096 client->engine = NULL;
2099 if (client->port_segment) {
2100 jack_port_type_id_t ptid;
2101 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
2102 jack_release_shm (&client->port_segment[ptid]);
2104 free (client->port_segment);
2105 client->port_segment = NULL;
2108 #ifndef JACK_USE_MACH_THREADS
2109 if (client->graph_wait_fd >= 0) {
2110 close (client->graph_wait_fd);
2113 if (client->graph_next_fd >= 0) {
2114 close (client->graph_next_fd);
2116 #endif
2118 close (client->event_fd);
2120 if (shutdown (client->request_fd, SHUT_RDWR)) {
2121 jack_error ("could not shutdown client request socket");
2124 close (client->request_fd);
2128 for (node = client->ports; node; node = jack_slist_next (node)) {
2129 free (node->data);
2131 jack_slist_free (client->ports);
2132 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
2133 free (node->data);
2135 jack_slist_free (client->ports_ext);
2136 jack_client_free (client);
2137 jack_messagebuffer_exit ();
2139 return rc;
2143 jack_client_close (jack_client_t *client)
2145 return jack_client_close_aux(client);
2148 int
2149 jack_is_realtime (jack_client_t *client)
2151 return client->engine->real_time;
2154 jack_nframes_t
2155 jack_get_buffer_size (jack_client_t *client)
2157 return client->engine->buffer_size;
2161 jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
2163 #ifdef DO_BUFFER_RESIZE
2164 jack_request_t req;
2166 req.type = SetBufferSize;
2167 req.x.nframes = nframes;
2169 return jack_client_deliver_request (client, &req);
2170 #else
2171 return ENOSYS;
2173 #endif /* DO_BUFFER_RESIZE */
2176 int
2177 jack_connect (jack_client_t *client, const char *source_port,
2178 const char *destination_port)
2180 jack_request_t req;
2182 req.type = ConnectPorts;
2184 snprintf (req.x.connect.source_port,
2185 sizeof (req.x.connect.source_port), "%s", source_port);
2186 snprintf (req.x.connect.destination_port,
2187 sizeof (req.x.connect.destination_port),
2188 "%s", destination_port);
2190 return jack_client_deliver_request (client, &req);
2194 jack_port_disconnect (jack_client_t *client, jack_port_t *port)
2196 jack_request_t req;
2198 pthread_mutex_lock (&port->connection_lock);
2200 if (port->connections == NULL) {
2201 pthread_mutex_unlock (&port->connection_lock);
2202 return 0;
2205 pthread_mutex_unlock (&port->connection_lock);
2207 req.type = DisconnectPort;
2208 req.x.port_info.port_id = port->shared->id;
2210 return jack_client_deliver_request (client, &req);
2213 int
2214 jack_disconnect (jack_client_t *client, const char *source_port,
2215 const char *destination_port)
2217 jack_request_t req;
2219 req.type = DisconnectPorts;
2221 snprintf (req.x.connect.source_port,
2222 sizeof (req.x.connect.source_port), "%s", source_port);
2223 snprintf (req.x.connect.destination_port,
2224 sizeof (req.x.connect.destination_port),
2225 "%s", destination_port);
2227 return jack_client_deliver_request (client, &req);
2230 void
2231 jack_set_error_function (void (*func) (const char *))
2233 jack_error_callback = func;
2236 void
2237 jack_set_info_function (void (*func) (const char *))
2239 jack_info_callback = func;
2242 int
2243 jack_set_graph_order_callback (jack_client_t *client,
2244 JackGraphOrderCallback callback, void *arg)
2246 if (client->control->active) {
2247 jack_error ("You cannot set callbacks on an active client.");
2248 return -1;
2250 client->graph_order = callback;
2251 client->graph_order_arg = arg;
2252 client->control->graph_order_cbset = (callback != NULL);
2253 return 0;
2256 int jack_set_xrun_callback (jack_client_t *client,
2257 JackXRunCallback callback, void *arg)
2259 if (client->control->active) {
2260 jack_error ("You cannot set callbacks on an active client.");
2261 return -1;
2264 client->xrun = callback;
2265 client->xrun_arg = arg;
2266 client->control->xrun_cbset = (callback != NULL);
2267 return 0;
2271 jack_set_process_callback (jack_client_t *client,
2272 JackProcessCallback callback, void *arg)
2275 if (client->control->active) {
2276 jack_error ("You cannot set callbacks on an active client.");
2277 return -1;
2280 if (client->control->thread_cb_cbset) {
2281 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
2282 return -1;
2285 client->process_arg = arg;
2286 client->process = callback;
2287 client->control->process_cbset = (callback != NULL);
2288 return 0;
2292 jack_set_thread_init_callback (jack_client_t *client,
2293 JackThreadInitCallback callback, void *arg)
2296 if (client->control->active) {
2297 jack_error ("You cannot set callbacks on an active client.");
2298 return -1;
2300 client->thread_init_arg = arg;
2301 client->thread_init = callback;
2302 client->control->thread_init_cbset = (callback != NULL);
2303 return 0;
2307 jack_set_freewheel_callback (jack_client_t *client,
2308 JackFreewheelCallback callback, void *arg)
2310 if (client->control->active) {
2311 jack_error ("You cannot set callbacks on an active client.");
2312 return -1;
2314 client->freewheel_arg = arg;
2315 client->freewheel_cb = callback;
2316 client->control->freewheel_cb_cbset = (callback != NULL);
2317 return 0;
2321 jack_set_buffer_size_callback (jack_client_t *client,
2322 JackBufferSizeCallback callback, void *arg)
2324 client->bufsize_arg = arg;
2325 client->bufsize = callback;
2326 client->control->bufsize_cbset = (callback != NULL);
2327 return 0;
2331 jack_set_port_registration_callback(jack_client_t *client,
2332 JackPortRegistrationCallback callback,
2333 void *arg)
2335 if (client->control->active) {
2336 jack_error ("You cannot set callbacks on an active client.");
2337 return -1;
2339 client->port_register_arg = arg;
2340 client->port_register = callback;
2341 client->control->port_register_cbset = (callback != NULL);
2342 return 0;
2346 jack_set_port_connect_callback(jack_client_t *client,
2347 JackPortConnectCallback callback,
2348 void *arg)
2350 if (client->control->active) {
2351 jack_error ("You cannot set callbacks on an active client.");
2352 return -1;
2354 client->port_connect_arg = arg;
2355 client->port_connect = callback;
2356 client->control->port_connect_cbset = (callback != NULL);
2357 return 0;
2361 jack_set_client_registration_callback(jack_client_t *client,
2362 JackClientRegistrationCallback callback,
2363 void *arg)
2365 if (client->control->active) {
2366 jack_error ("You cannot set callbacks on an active client.");
2367 return -1;
2369 client->client_register_arg = arg;
2370 client->client_register = callback;
2371 client->control->client_register_cbset = (callback != NULL);
2372 return 0;
2376 jack_set_process_thread(jack_client_t* client, JackThreadCallback callback, void *arg)
2378 if (client->control->active) {
2379 jack_error ("You cannot set callbacks on an active client.");
2380 return -1;
2383 if (client->control->process_cbset) {
2384 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
2385 return -1;
2388 client->thread_cb_arg = arg;
2389 client->thread_cb = callback;
2390 client->control->thread_cb_cbset = (callback != NULL);
2391 return 0;
2395 jack_get_process_done_fd (jack_client_t *client)
2397 return client->graph_next_fd;
2400 void
2401 jack_on_shutdown (jack_client_t *client, void (*function)(void *arg), void *arg)
2403 client->on_shutdown = function;
2404 client->on_shutdown_arg = arg;
2407 void
2408 jack_on_info_shutdown (jack_client_t *client, void (*function)(jack_status_t, const char*, void *arg), void *arg)
2410 client->on_info_shutdown = function;
2411 client->on_info_shutdown_arg = arg;
2414 const char **
2415 jack_get_ports (jack_client_t *client,
2416 const char *port_name_pattern,
2417 const char *type_name_pattern,
2418 unsigned long flags)
2420 jack_control_t *engine;
2421 const char **matching_ports;
2422 unsigned long match_cnt;
2423 jack_port_shared_t *psp;
2424 unsigned long i;
2425 regex_t port_regex;
2426 regex_t type_regex;
2427 int matching;
2429 engine = client->engine;
2431 if (port_name_pattern && port_name_pattern[0]) {
2432 regcomp (&port_regex, port_name_pattern,
2433 REG_EXTENDED|REG_NOSUB);
2435 if (type_name_pattern && type_name_pattern[0]) {
2436 regcomp (&type_regex, type_name_pattern,
2437 REG_EXTENDED|REG_NOSUB);
2440 psp = engine->ports;
2441 match_cnt = 0;
2443 matching_ports = (const char **)
2444 malloc (sizeof (char *) * engine->port_max);
2446 for (i = 0; i < engine->port_max; i++) {
2447 matching = 1;
2449 if (!psp[i].in_use) {
2450 continue;
2453 if (flags) {
2454 if ((psp[i].flags & flags) != flags) {
2455 matching = 0;
2459 if (matching && port_name_pattern && port_name_pattern[0]) {
2460 if (regexec (&port_regex, psp[i].name, 0, NULL, 0)) {
2461 matching = 0;
2465 if (matching && type_name_pattern && type_name_pattern[0]) {
2466 jack_port_type_id_t ptid = psp[i].ptype_id;
2467 if (regexec (&type_regex,
2468 engine->port_types[ptid].type_name,
2469 0, NULL, 0)) {
2470 matching = 0;
2474 if (matching) {
2475 matching_ports[match_cnt++] = psp[i].name;
2478 if (port_name_pattern && port_name_pattern[0]) {
2479 regfree (&port_regex);
2481 if (type_name_pattern && type_name_pattern[0]) {
2482 regfree (&type_regex);
2485 matching_ports[match_cnt] = 0;
2487 if (match_cnt == 0) {
2488 free (matching_ports);
2489 matching_ports = 0;
2492 return matching_ports;
2495 float
2496 jack_cpu_load (jack_client_t *client)
2498 return client->engine->cpu_load;
2501 float
2502 jack_get_xrun_delayed_usecs (jack_client_t *client)
2504 return client->engine->xrun_delayed_usecs;
2507 float
2508 jack_get_max_delayed_usecs (jack_client_t *client)
2510 return client->engine->max_delayed_usecs;
2513 void
2514 jack_reset_max_delayed_usecs (jack_client_t *client)
2516 client->engine->max_delayed_usecs = 0.0f;
2519 pthread_t
2520 jack_client_thread_id (jack_client_t *client)
2522 return client->thread_id;
2526 jack_client_name_size(void)
2528 return JACK_CLIENT_NAME_SIZE;
2532 jack_port_name_size(void)
2534 return JACK_PORT_NAME_SIZE;
2538 jack_port_type_size(void)
2540 return JACK_PORT_TYPE_SIZE;
2543 void
2544 jack_free (void* ptr)
2546 free (ptr);