ensure that client-side message buffer thread calls thread_init callback if/when...
[jack.git] / libjack / client.c
blobfcde6c8cbf1c4ab70c3647f5c787b0a17dd14e32
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>
51 #include <jack/messagebuffer.h>
53 #include <sysdeps/time.h>
55 #include "local.h"
57 #include <sysdeps/poll.h>
58 #include <sysdeps/ipc.h>
59 #include <sysdeps/cycles.h>
61 #ifdef JACK_USE_MACH_THREADS
62 #include <sysdeps/pThreadUtilities.h>
63 #endif
65 static pthread_mutex_t client_lock;
66 static pthread_cond_t client_ready;
68 static int
69 jack_client_close_aux (jack_client_t *client);
71 #define EVENT_POLL_INDEX 0
72 #define WAIT_POLL_INDEX 1
73 #define event_fd pollfd[EVENT_POLL_INDEX].fd
74 #define graph_wait_fd pollfd[WAIT_POLL_INDEX].fd
76 typedef struct {
77 int status;
78 struct _jack_client *client;
79 const char *client_name;
80 } client_info;
82 #ifdef USE_DYNSIMD
84 #ifdef ARCH_X86
86 int cpu_type = 0;
88 static void
89 init_cpu ()
91 cpu_type = ((have_3dnow() << 8) | have_sse());
92 if (ARCH_X86_HAVE_3DNOW(cpu_type))
93 jack_info("Enhanced3DNow! detected");
94 if (ARCH_X86_HAVE_SSE2(cpu_type))
95 jack_info("SSE2 detected");
96 if ((!ARCH_X86_HAVE_3DNOW(cpu_type)) && (!ARCH_X86_HAVE_SSE2(cpu_type)))
97 jack_info("No supported SIMD instruction sets detected");
98 jack_port_set_funcs();
101 #else /* ARCH_X86 */
103 static void
104 init_cpu ()
106 jack_port_set_funcs();
109 #endif /* ARCH_X86 */
111 #endif /* USE_DYNSIMD */
113 char *jack_tmpdir = DEFAULT_TMP_DIR;
115 static int
116 jack_get_tmpdir ()
118 FILE* in;
119 size_t len;
120 char buf[PATH_MAX+2]; /* allow tmpdir to live anywhere, plus newline, plus null */
121 char *pathenv;
122 char *pathcopy;
123 char *p;
125 /* some implementations of popen(3) close a security loophole by
126 resetting PATH for the exec'd command. since we *want* to
127 use the user's PATH setting to locate jackd, we have to
128 do it ourselves.
131 if ((pathenv = getenv ("PATH")) == 0) {
132 return -1;
135 /* don't let strtok(3) mess with the real environment variable */
137 if ((pathcopy = strdup (pathenv)) == NULL) {
138 return -1;
140 p = strtok (pathcopy, ":");
142 while (p) {
143 char jackd[PATH_MAX+1];
144 char command[PATH_MAX+4];
146 snprintf (jackd, sizeof (jackd), "%s/jackd", p);
148 if (access (jackd, X_OK) == 0) {
150 snprintf (command, sizeof (command), "%s -l", jackd);
152 if ((in = popen (command, "r")) != NULL) {
153 break;
157 p = strtok (NULL, ":");
160 if (p == NULL) {
161 /* no command successfully started */
162 free (pathcopy);
163 return -1;
166 if (fgets (buf, sizeof (buf), in) == NULL) {
167 fclose (in);
168 free (pathcopy);
169 return -1;
172 len = strlen (buf);
174 if (buf[len-1] != '\n') {
175 /* didn't get a whole line */
176 fclose (in);
177 free (pathcopy);
178 return -1;
181 if ((jack_tmpdir = (char *) malloc (len)) == NULL) {
182 free (pathcopy);
183 return -1;
186 memcpy (jack_tmpdir, buf, len-1);
187 jack_tmpdir[len-1] = '\0';
189 fclose (in);
190 free (pathcopy);
192 return 0;
195 void
196 jack_error (const char *fmt, ...)
198 va_list ap;
199 char buffer[300];
201 va_start (ap, fmt);
202 vsnprintf (buffer, sizeof(buffer), fmt, ap);
203 jack_error_callback (buffer);
204 va_end (ap);
207 void
208 default_jack_error_callback (const char *desc)
210 #ifdef DEBUG_ENABLED
211 DEBUG("%s", desc);
212 #else
213 fprintf(stderr, "%s\n", desc);
214 fflush(stderr);
215 #endif
218 void
219 default_jack_info_callback (const char *desc)
221 fprintf(stdout, "%s\n", desc);
222 fflush(stdout);
225 void
226 silent_jack_error_callback (const char *desc)
230 void (*jack_error_callback)(const char *desc) = &default_jack_error_callback;
231 void (*jack_info_callback)(const char *desc) = &default_jack_info_callback;
233 void
234 jack_info (const char *fmt, ...)
236 va_list ap;
237 char buffer[300];
239 va_start (ap, fmt);
240 vsnprintf (buffer, sizeof(buffer), fmt, ap);
241 jack_info_callback (buffer);
242 va_end (ap);
245 static int
246 oop_client_deliver_request (void *ptr, jack_request_t *req)
248 int wok, rok;
249 jack_client_t *client = (jack_client_t*) ptr;
251 wok = (write (client->request_fd, req, sizeof (*req))
252 == sizeof (*req));
253 rok = (read (client->request_fd, req, sizeof (*req))
254 == sizeof (*req));
256 if (wok && rok) { /* everything OK? */
257 return req->status;
260 req->status = -1; /* request failed */
262 /* check for server shutdown */
263 if (client->engine->engine_ok == 0)
264 return req->status;
266 /* otherwise report errors */
267 if (!wok)
268 jack_error ("cannot send request type %d to server",
269 req->type);
270 if (!rok)
271 jack_error ("cannot read result for request type %d from"
272 " server (%s)", req->type, strerror (errno));
273 return req->status;
277 jack_client_deliver_request (const jack_client_t *client, jack_request_t *req)
279 /* indirect through the function pointer that was set either
280 * by jack_client_open() or by jack_new_client_request() in
281 * the server.
284 return client->deliver_request (client->deliver_arg,
285 req);
288 #if JACK_USE_MACH_THREADS
290 jack_client_t *
291 jack_client_alloc ()
293 jack_client_t *client;
295 if ((client = (jack_client_t *) malloc (sizeof (jack_client_t))) == NULL) {
296 return NULL;
299 if ((client->pollfd = (struct pollfd *) malloc (sizeof (struct pollfd) * 1)) == NULL) {
300 free (client);
301 return NULL;
304 client->pollmax = 1;
305 client->request_fd = -1;
306 client->event_fd = -1;
307 client->upstream_is_jackd = 0;
308 client->graph_wait_fd = -1;
309 client->graph_next_fd = -1;
310 client->ports = NULL;
311 client->ports_ext = NULL;
312 client->engine = NULL;
313 client->control = NULL;
314 client->thread_ok = FALSE;
315 client->rt_thread_ok = FALSE;
316 client->first_active = TRUE;
317 client->on_shutdown = NULL;
318 client->on_info_shutdown = NULL;
319 client->n_port_types = 0;
320 client->port_segment = NULL;
322 #ifdef USE_DYNSIMD
323 init_cpu();
324 #endif /* USE_DYNSIMD */
326 return client;
329 #else
331 jack_client_t *
332 jack_client_alloc ()
334 jack_client_t *client;
336 if ((client = (jack_client_t *) malloc (sizeof (jack_client_t))) == NULL) {
337 return NULL;
339 if ((client->pollfd = (struct pollfd *) malloc (sizeof (struct pollfd) * 2)) == NULL) {
340 free (client);
341 return NULL;
344 client->pollmax = 2;
345 client->request_fd = -1;
346 client->event_fd = -1;
347 client->upstream_is_jackd = 0;
348 client->graph_wait_fd = -1;
349 client->graph_next_fd = -1;
350 client->ports = NULL;
351 client->ports_ext = NULL;
352 client->engine = NULL;
353 client->control = NULL;
354 client->thread_ok = FALSE;
355 client->first_active = TRUE;
356 client->on_shutdown = NULL;
357 client->on_info_shutdown = NULL;
358 client->n_port_types = 0;
359 client->port_segment = NULL;
361 #ifdef USE_DYNSIMD
362 init_cpu();
363 #endif /* USE_DYNSIMD */
365 return client;
368 #endif
371 * Build the jack_client_t structure for an internal client.
373 jack_client_t *
374 jack_client_alloc_internal (jack_client_control_t *cc, jack_engine_t* engine)
376 jack_client_t* client;
378 client = jack_client_alloc ();
380 client->control = cc;
381 client->engine = engine->control;
383 client->n_port_types = client->engine->n_port_types;
384 client->port_segment = &engine->port_segment[0];
386 return client;
389 static void
390 jack_client_free (jack_client_t *client)
392 if (client->pollfd) {
393 free (client->pollfd);
396 free (client);
399 void
400 jack_client_invalidate_port_buffers (jack_client_t *client)
402 JSList *node;
403 jack_port_t *port;
405 /* This releases all local memory owned by input ports
406 and sets the buffer pointer to NULL. This will cause
407 jack_port_get_buffer() to reallocate space for the
408 buffer on the next call (if there is one).
411 for (node = client->ports; node; node = jack_slist_next (node)) {
412 port = (jack_port_t *) node->data;
414 if (port->shared->flags & JackPortIsInput) {
415 if (port->mix_buffer) {
416 jack_pool_release (port->mix_buffer);
417 port->mix_buffer = NULL;
424 jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)
426 jack_port_t *control_port;
427 jack_port_t *other = 0;
428 JSList *node;
429 int need_free = FALSE;
431 if (client->engine->ports[event->x.self_id].client_id == client->control->id ||
432 client->engine->ports[event->y.other_id].client_id == client->control->id) {
434 /* its one of ours */
436 switch (event->type) {
437 case PortConnected:
438 other = jack_port_new (client, event->y.other_id,
439 client->engine);
440 /* jack_port_by_id_int() always returns an internal
441 * port that does not need to be deallocated
443 control_port = jack_port_by_id_int (client, event->x.self_id,
444 &need_free);
445 pthread_mutex_lock (&control_port->connection_lock);
446 control_port->connections =
447 jack_slist_prepend (control_port->connections,
448 (void *) other);
449 pthread_mutex_unlock (&control_port->connection_lock);
450 break;
452 case PortDisconnected:
453 /* jack_port_by_id_int() always returns an internal
454 * port that does not need to be deallocated
456 control_port = jack_port_by_id_int (client, event->x.self_id,
457 &need_free);
458 pthread_mutex_lock (&control_port->connection_lock);
460 for (node = control_port->connections; node;
461 node = jack_slist_next (node)) {
463 other = (jack_port_t *) node->data;
465 if (other->shared->id == event->y.other_id) {
466 control_port->connections =
467 jack_slist_remove_link (
468 control_port->connections,
469 node);
470 jack_slist_free_1 (node);
471 free (other);
472 break;
476 pthread_mutex_unlock (&control_port->connection_lock);
477 break;
479 default:
480 /* impossible */
481 break;
485 if (client->control->port_connect_cbset) {
486 client->port_connect (event->x.self_id, event->y.other_id,
487 (event->type == PortConnected ? 1 : 0),
488 client->port_connect_arg);
491 return 0;
494 #if JACK_USE_MACH_THREADS
496 static int
497 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
499 client->pollmax = 1;
501 /* If the client registered its own callback for graph order events,
502 execute it now.
505 if (client->control->graph_order_cbset) {
506 client->graph_order (client->graph_order_arg);
509 return 0;
512 #else
514 static int
515 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
517 char path[PATH_MAX+1];
519 DEBUG ("graph reorder\n");
521 if (client->graph_wait_fd >= 0) {
522 DEBUG ("closing graph_wait_fd==%d", client->graph_wait_fd);
523 close (client->graph_wait_fd);
524 client->graph_wait_fd = -1;
527 if (client->graph_next_fd >= 0) {
528 DEBUG ("closing graph_next_fd==%d", client->graph_next_fd);
529 close (client->graph_next_fd);
530 client->graph_next_fd = -1;
533 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n);
535 if ((client->graph_wait_fd = open (path, O_RDONLY|O_NONBLOCK)) < 0) {
536 jack_error ("cannot open specified fifo [%s] for reading (%s)",
537 path, strerror (errno));
538 return -1;
540 DEBUG ("opened new graph_wait_fd %d (%s)", client->graph_wait_fd, path);
542 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n+1);
544 if ((client->graph_next_fd = open (path, O_WRONLY|O_NONBLOCK)) < 0) {
545 jack_error ("cannot open specified fifo [%s] for writing (%s)",
546 path, strerror (errno));
547 return -1;
550 client->upstream_is_jackd = event->y.n;
551 client->pollmax = 2;
553 DEBUG ("opened new graph_next_fd %d (%s) (upstream is jackd? %d)",
554 client->graph_next_fd, path,
555 client->upstream_is_jackd);
557 /* If the client registered its own callback for graph order events,
558 execute it now.
561 if (client->control->graph_order_cbset) {
562 client->graph_order (client->graph_order_arg);
565 return 0;
568 #endif
570 static int
571 server_connect (const char *server_name)
573 int fd;
574 struct sockaddr_un addr;
575 int which = 0;
577 char server_dir[PATH_MAX+1] = "";
579 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
580 jack_error ("cannot create client socket (%s)",
581 strerror (errno));
582 return -1;
585 //JOQ: temporary debug message
586 //jack_info ("DEBUG: connecting to `%s' server", server_name);
588 addr.sun_family = AF_UNIX;
589 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_%d",
590 jack_server_dir (server_name, server_dir) , which);
592 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
593 close (fd);
594 return -1;
597 return fd;
600 static int
601 server_event_connect (jack_client_t *client, const char *server_name)
603 int fd;
604 struct sockaddr_un addr;
605 jack_client_connect_ack_request_t req;
606 jack_client_connect_ack_result_t res;
608 char server_dir[PATH_MAX+1] = "";
610 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
611 jack_error ("cannot create client event socket (%s)",
612 strerror (errno));
613 return -1;
616 addr.sun_family = AF_UNIX;
617 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_ack_0",
618 jack_server_dir (server_name,server_dir));
620 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
621 jack_error ("cannot connect to jack server for events",
622 strerror (errno));
623 close (fd);
624 return -1;
627 req.client_id = client->control->id;
629 if (write (fd, &req, sizeof (req)) != sizeof (req)) {
630 jack_error ("cannot write event connect request to server (%s)",
631 strerror (errno));
632 close (fd);
633 return -1;
636 if (read (fd, &res, sizeof (res)) != sizeof (res)) {
637 jack_error ("cannot read event connect result from server (%s)",
638 strerror (errno));
639 close (fd);
640 return -1;
643 if (res.status != 0) {
644 jack_error ("cannot connect to server for event stream (%s)",
645 strerror (errno));
646 close (fd);
647 return -1;
650 return fd;
653 /* Exec the JACK server in this process. Does not return. */
654 static void
655 _start_server (const char *server_name)
657 FILE* fp = 0;
658 char filename[255];
659 char arguments[255];
660 char buffer[255];
661 char* command = 0;
662 size_t pos = 0;
663 size_t result = 0;
664 char** argv = 0;
665 int i = 0;
666 int good = 0;
667 int ret;
669 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
670 fp = fopen(filename, "r");
672 if (!fp) {
673 fp = fopen("/etc/jackdrc", "r");
675 /* if still not found, check old config name for backwards compatability */
676 if (!fp) {
677 fp = fopen("/etc/jackd.conf", "r");
680 if (fp) {
681 arguments[0] = '\0';
682 ret = fscanf(fp, "%s", buffer);
683 while(ret != 0 && ret != EOF) {
684 strcat(arguments, buffer);
685 strcat(arguments, " ");
686 ret = fscanf(fp, "%s", buffer);
688 if (strlen(arguments) > 0) {
689 good = 1;
693 if (!good) {
694 #if defined(USE_CAPABILITIES)
695 command = JACK_LOCATION "/jackstart";
696 strncpy(arguments, JACK_LOCATION "/jackstart -T -R -d "
697 JACK_DEFAULT_DRIVER " -p 512", 255);
698 #else /* !USE_CAPABILITIES */
699 command = JACK_LOCATION "/jackd";
700 strncpy(arguments, JACK_LOCATION "/jackd -T -d "
701 JACK_DEFAULT_DRIVER, 255);
702 #endif /* USE_CAPABILITIES */
703 } else {
704 result = strcspn(arguments, " ");
705 if ((command = (char *) malloc(result+1)) == NULL) {
706 goto failure;
708 strncpy(command, arguments, result);
709 command[result] = '\0';
712 if ((argv = (char **) malloc (255)) == NULL) {
713 goto failure;
716 while(1) {
717 /* insert -T and -nserver_name in front of arguments */
718 if (i == 1) {
719 argv[i] = (char *) malloc(strlen ("-T") + 1);
720 strcpy (argv[i++], "-T");
721 if (server_name) {
722 size_t optlen = strlen ("-n");
723 char *buf =
724 malloc (optlen
725 + strlen (server_name) + 1);
726 strcpy (buf, "-n");
727 strcpy (buf+optlen, server_name);
728 argv[i++] = buf;
732 result = strcspn(arguments+pos, " ");
733 if (result == 0) {
734 break;
736 argv[i] = (char*)malloc(result+1);
738 strncpy(argv[i], arguments+pos, result);
739 argv[i][result] = '\0';
741 pos += result+1;
742 ++i;
744 argv[i] = 0;
746 #if 0
747 fprintf (stderr, "execing JACK using %s\n", command);
748 for (_xx = 0; argv[_xx]; ++_xx) {
749 fprintf (stderr, "\targv[%d] = %s\n", _xx, argv[_xx]);
751 #endif
753 execv (command, argv);
755 failure:
756 /* If execv() succeeds, it does not return. There's no point
757 * in calling jack_error() here in the child process. */
758 fprintf (stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror (errno));
762 start_server (const char *server_name, jack_options_t options)
764 if ((options & JackNoStartServer)
765 || getenv("JACK_NO_START_SERVER")) {
766 return 1;
769 /* The double fork() forces the server to become a child of
770 * init, which will always clean up zombie process state on
771 * termination. This even works in cases where the server
772 * terminates but this client does not.
774 * Since fork() is usually implemented using copy-on-write
775 * virtual memory tricks, the overhead of the second fork() is
776 * probably relatively small.
778 switch (fork()) {
779 case 0: /* child process */
780 switch (fork()) {
781 case 0: /* grandchild process */
782 _start_server(server_name);
783 _exit (99); /* exec failed */
784 case -1:
785 _exit (98);
786 default:
787 _exit (0);
789 case -1: /* fork() error */
790 return 1; /* failed to start server */
793 /* only the original parent process goes here */
794 return 0; /* (probably) successful */
797 static int
798 jack_request_client (ClientType type,
799 const char* client_name, jack_options_t options,
800 jack_status_t *status, jack_varargs_t *va,
801 jack_client_connect_result_t *res, int *req_fd)
803 jack_client_connect_request_t req;
805 *req_fd = -1;
806 memset (&req, 0, sizeof (req));
807 req.options = options;
809 if (strlen (client_name) >= sizeof (req.name)) {
810 jack_error ("\"%s\" is too long to be used as a JACK client"
811 " name.\n"
812 "Please use %lu characters or less.",
813 client_name, sizeof (req.name));
814 return -1;
817 if (va->load_name
818 && (strlen (va->load_name) > sizeof (req.object_path) - 1)) {
819 jack_error ("\"%s\" is too long to be used as a JACK shared"
820 " object name.\n"
821 "Please use %lu characters or less.",
822 va->load_name, sizeof (req.object_path) - 1);
823 return -1;
826 if (va->load_init
827 && (strlen (va->load_init) > sizeof (req.object_data) - 1)) {
828 jack_error ("\"%s\" is too long to be used as a JACK shared"
829 " object data string.\n"
830 "Please use %lu characters or less.",
831 va->load_init, sizeof (req.object_data) - 1);
832 return -1;
835 if ((*req_fd = server_connect (va->server_name)) < 0) {
836 int trys;
837 if (start_server(va->server_name, options)) {
838 *status |= (JackFailure|JackServerFailed);
839 goto fail;
841 trys = 5;
842 do {
843 sleep(1);
844 if (--trys < 0) {
845 *status |= (JackFailure|JackServerFailed);
846 goto fail;
848 } while ((*req_fd = server_connect (va->server_name)) < 0);
849 *status |= JackServerStarted;
852 /* format connection request */
854 req.protocol_v = jack_protocol_version;
855 req.load = TRUE;
856 req.type = type;
857 snprintf (req.name, sizeof (req.name),
858 "%s", client_name);
859 snprintf (req.object_path, sizeof (req.object_path),
860 "%s", va->load_name);
861 snprintf (req.object_data, sizeof (req.object_data),
862 "%s", va->load_init);
864 if (write (*req_fd, &req, sizeof (req)) != sizeof (req)) {
865 jack_error ("cannot send request to jack server (%s)",
866 strerror (errno));
867 *status |= (JackFailure|JackServerError);
868 goto fail;
871 if (read (*req_fd, res, sizeof (*res)) != sizeof (*res)) {
873 if (errno == 0) {
874 /* server shut the socket */
875 jack_error ("could not attach as client");
876 *status |= (JackFailure|JackServerError);
877 goto fail;
880 if (errno == ECONNRESET) {
881 jack_error ("could not attach as JACK client "
882 "(server has exited)");
883 *status |= (JackFailure|JackServerError);
884 goto fail;
887 jack_error ("cannot read response from jack server (%s)",
888 strerror (errno));
889 *status |= (JackFailure|JackServerError);
890 goto fail;
893 *status |= res->status; /* return server status bits */
895 if (*status & JackFailure) {
896 if (*status & JackVersionError) {
897 jack_error ("client linked with incompatible libjack"
898 " version.");
900 jack_error ("could not attach to JACK server");
901 *status |= JackServerError;
902 goto fail;
905 switch (type) {
906 case ClientDriver:
907 case ClientInternal:
908 close (*req_fd);
909 *req_fd = -1;
910 break;
912 default:
913 break;
916 return 0;
918 fail:
919 if (*req_fd >= 0) {
920 close (*req_fd);
921 *req_fd = -1;
923 return -1;
927 jack_attach_port_segment (jack_client_t *client, jack_port_type_id_t ptid)
929 /* Lookup, attach and register the port/buffer segments in use
930 * right now.
933 if (client->control->type != ClientExternal) {
934 jack_error("Only external clients need attach port segments");
935 abort();
938 /* make sure we have space to store the port
939 segment information.
942 if (ptid >= client->n_port_types) {
944 client->port_segment = (jack_shm_info_t*)
945 realloc (client->port_segment,
946 sizeof (jack_shm_info_t) * (ptid+1));
948 memset (&client->port_segment[client->n_port_types],
950 sizeof (jack_shm_info_t) *
951 (ptid - client->n_port_types));
953 client->n_port_types = ptid + 1;
955 } else {
957 /* release any previous segment */
958 jack_release_shm (&client->port_segment[ptid]);
961 /* get the index into the shm registry */
963 client->port_segment[ptid].index =
964 client->engine->port_types[ptid].shm_registry_index;
966 /* attach the relevant segment */
968 if (jack_attach_shm (&client->port_segment[ptid])) {
969 jack_error ("cannot attach port segment shared memory"
970 " (%s)", strerror (errno));
971 return -1;
974 return 0;
977 jack_client_t *
978 jack_client_open_aux (const char *client_name,
979 jack_options_t options,
980 jack_status_t *status, va_list ap)
982 /* optional arguments: */
983 jack_varargs_t va; /* variable arguments */
985 int req_fd = -1;
986 int ev_fd = -1;
987 jack_client_connect_result_t res;
988 jack_client_t *client;
989 jack_port_type_id_t ptid;
990 jack_status_t my_status;
992 jack_messagebuffer_init ();
994 if (status == NULL) /* no status from caller? */
995 status = &my_status; /* use local status word */
996 *status = 0;
998 /* validate parameters */
999 if ((options & ~JackOpenOptions)) {
1000 *status |= (JackFailure|JackInvalidOption);
1001 jack_messagebuffer_exit ();
1002 return NULL;
1005 /* parse variable arguments */
1006 jack_varargs_parse(options, ap, &va);
1008 /* External clients need to know where the tmpdir used for
1009 communication with the server lives
1011 if (jack_get_tmpdir ()) {
1012 *status |= JackFailure;
1013 jack_messagebuffer_exit ();
1014 return NULL;
1017 /* External clients need this initialized. It is already set
1018 * up in the server's address space for internal clients.
1020 jack_init_time ();
1022 if (jack_request_client (ClientExternal, client_name, options, status,
1023 &va, &res, &req_fd)) {
1024 jack_messagebuffer_exit ();
1025 return NULL;
1028 /* Allocate the jack_client_t structure in local memory.
1029 * Shared memory is not accessible yet. */
1030 client = jack_client_alloc ();
1031 strcpy (client->name, res.name);
1032 strcpy (client->fifo_prefix, res.fifo_prefix);
1033 client->request_fd = req_fd;
1034 client->pollfd[EVENT_POLL_INDEX].events =
1035 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1036 #ifndef JACK_USE_MACH_THREADS
1037 client->pollfd[WAIT_POLL_INDEX].events =
1038 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1039 #endif
1041 /* Don't access shared memory until server connected. */
1042 if (jack_initialize_shm (va.server_name)) {
1043 jack_error ("Unable to initialize shared memory.");
1044 *status |= (JackFailure|JackShmFailure);
1045 goto fail;
1048 /* attach the engine control/info block */
1049 client->engine_shm.index = res.engine_shm_index;
1050 if (jack_attach_shm (&client->engine_shm)) {
1051 jack_error ("cannot attached engine control shared memory"
1052 " segment");
1053 goto fail;
1056 client->engine = (jack_control_t *) jack_shm_addr (&client->engine_shm);
1058 /* initialize clock source as early as possible */
1059 jack_set_clock_source (client->engine->clock_source);
1061 /* now attach the client control block */
1062 client->control_shm.index = res.client_shm_index;
1063 if (jack_attach_shm (&client->control_shm)) {
1064 jack_error ("cannot attached client control shared memory"
1065 " segment");
1066 goto fail;
1069 client->control = (jack_client_control_t *)
1070 jack_shm_addr (&client->control_shm);
1072 /* Nobody else needs to access this shared memory any more, so
1073 * destroy it. Because we have it attached, it won't vanish
1074 * till we exit (and release it).
1076 jack_destroy_shm (&client->control_shm);
1078 client->n_port_types = client->engine->n_port_types;
1079 if ((client->port_segment = (jack_shm_info_t *) malloc (sizeof (jack_shm_info_t) * client->n_port_types)) == NULL) {
1080 goto fail;
1083 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
1084 client->port_segment[ptid].index =
1085 client->engine->port_types[ptid].shm_registry_index;
1086 client->port_segment[ptid].attached_at = MAP_FAILED;
1087 jack_attach_port_segment (client, ptid);
1090 /* set up the client so that it does the right thing for an
1091 * external client
1093 client->deliver_request = oop_client_deliver_request;
1094 client->deliver_arg = client;
1096 if ((ev_fd = server_event_connect (client, va.server_name)) < 0) {
1097 goto fail;
1100 client->event_fd = ev_fd;
1102 #ifdef JACK_USE_MACH_THREADS
1103 /* specific resources for server/client real-time thread
1104 * communication */
1105 client->clienttask = mach_task_self();
1107 if (task_get_bootstrap_port(client->clienttask, &client->bp)){
1108 jack_error ("Can't find bootstrap port");
1109 goto fail;
1112 if (allocate_mach_clientport(client, res.portnum) < 0) {
1113 jack_error("Can't allocate mach port");
1114 goto fail;
1116 #endif /* JACK_USE_MACH_THREADS */
1117 return client;
1119 fail:
1120 jack_messagebuffer_exit ();
1122 if (client->engine) {
1123 jack_release_shm (&client->engine_shm);
1124 client->engine = 0;
1126 if (client->control) {
1127 jack_release_shm (&client->control_shm);
1128 client->control = 0;
1130 if (req_fd >= 0) {
1131 close (req_fd);
1133 if (ev_fd >= 0) {
1134 close (ev_fd);
1136 free (client);
1138 return NULL;
1141 jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
1143 va_list ap;
1144 va_start(ap, status);
1145 jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
1146 va_end(ap);
1147 return res;
1150 jack_client_t *
1151 jack_client_new (const char *client_name)
1153 jack_options_t options = JackUseExactName;
1154 if (getenv("JACK_START_SERVER") == NULL)
1155 options |= JackNoStartServer;
1156 return jack_client_open (client_name, options, NULL);
1159 char *
1160 jack_get_client_name (jack_client_t *client)
1162 return client->name;
1166 jack_internal_client_new (const char *client_name,
1167 const char *so_name, const char *so_data)
1169 jack_client_connect_result_t res;
1170 int req_fd;
1171 jack_varargs_t va;
1172 jack_status_t status;
1173 jack_options_t options = JackUseExactName;
1175 if (getenv("JACK_START_SERVER") == NULL)
1176 options |= JackNoStartServer;
1178 jack_varargs_init (&va);
1179 va.load_name = (char *) so_name;
1180 va.load_init = (char *) so_data;
1182 return jack_request_client (ClientInternal, client_name,
1183 options, &status, &va, &res, &req_fd);
1186 char *
1187 jack_default_server_name (void)
1189 char *server_name;
1190 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
1191 server_name = "default";
1192 return server_name;
1195 /* returns the name of the per-user subdirectory of jack_tmpdir */
1196 char *
1197 jack_user_dir (void)
1199 static char user_dir[PATH_MAX+1] = "";
1201 /* format the path name on the first call */
1202 if (user_dir[0] == '\0') {
1203 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
1204 snprintf (user_dir, sizeof (user_dir), "%s/jack",
1205 jack_tmpdir);
1206 } else {
1207 snprintf (user_dir, sizeof (user_dir), "%s/jack-%d",
1208 jack_tmpdir, getuid ());
1212 return user_dir;
1215 /* returns the name of the per-server subdirectory of jack_user_dir() */
1216 char *
1217 jack_server_dir (const char *server_name, char *server_dir)
1219 /* format the path name into the suppled server_dir char array,
1220 * assuming that server_dir is at least as large as PATH_MAX+1 */
1222 snprintf (server_dir, PATH_MAX+1, "%s/%s",
1223 jack_user_dir (), server_name);
1225 return server_dir;
1228 void
1229 jack_internal_client_close (const char *client_name)
1231 jack_client_connect_request_t req;
1232 int fd;
1233 char *server_name = jack_default_server_name ();
1235 req.load = FALSE;
1236 snprintf (req.name, sizeof (req.name), "%s", client_name);
1238 if ((fd = server_connect (server_name)) < 0) {
1239 return;
1242 if (write (fd, &req, sizeof (req)) != sizeof(req)) {
1243 jack_error ("cannot deliver ClientUnload request to JACK "
1244 "server.");
1247 /* no response to this request */
1249 close (fd);
1250 return;
1254 jack_recompute_total_latencies (jack_client_t* client)
1256 jack_request_t request;
1258 request.type = RecomputeTotalLatencies;
1259 return jack_client_deliver_request (client, &request);
1263 jack_recompute_total_latency (jack_client_t* client, jack_port_t* port)
1265 jack_request_t request;
1267 request.type = RecomputeTotalLatency;
1268 request.x.port_info.port_id = port->shared->id;
1269 return jack_client_deliver_request (client, &request);
1273 jack_set_freewheel (jack_client_t* client, int onoff)
1275 jack_request_t request;
1277 request.type = onoff ? FreeWheel : StopFreeWheel;
1278 return jack_client_deliver_request (client, &request);
1281 void
1282 jack_start_freewheel (jack_client_t* client)
1284 jack_client_control_t *control = client->control;
1286 if (client->engine->real_time) {
1287 #if JACK_USE_MACH_THREADS
1288 jack_drop_real_time_scheduling (client->process_thread);
1289 #else
1290 jack_drop_real_time_scheduling (client->thread);
1291 #endif
1294 if (control->freewheel_cb_cbset) {
1295 client->freewheel_cb (1, client->freewheel_arg);
1299 void
1300 jack_stop_freewheel (jack_client_t* client)
1302 jack_client_control_t *control = client->control;
1304 if (client->engine->real_time) {
1305 #if JACK_USE_MACH_THREADS
1306 jack_acquire_real_time_scheduling (client->process_thread,
1307 client->engine->client_priority);
1308 #else
1309 jack_acquire_real_time_scheduling (client->thread,
1310 client->engine->client_priority);
1311 #endif
1314 if (control->freewheel_cb_cbset) {
1315 client->freewheel_cb (0, client->freewheel_arg);
1319 static void
1320 jack_client_thread_suicide (jack_client_t* client)
1322 if (client->on_info_shutdown) {
1323 jack_error ("zombified - calling shutdown handler");
1324 client->on_info_shutdown (JackClientZombie, "Zombified", client->on_info_shutdown_arg);
1325 } else if (client->on_shutdown) {
1326 jack_error ("zombified - calling shutdown handler");
1327 client->on_shutdown (client->on_shutdown_arg);
1328 } else {
1329 jack_error ("jack_client_thread zombified - exiting from JACK");
1330 jack_client_close_aux (client);
1331 /* Need a fix : possibly make client crash if
1332 * zombified without shutdown handler
1336 pthread_exit (0);
1337 /*NOTREACHED*/
1340 static int
1341 jack_client_process_events (jack_client_t* client)
1343 jack_event_t event;
1344 char status = 0;
1345 jack_client_control_t *control = client->control;
1346 JSList *node;
1347 jack_port_t* port;
1349 DEBUG ("process events");
1351 if (client->pollfd[EVENT_POLL_INDEX].revents & POLLIN) {
1353 DEBUG ("client receives an event, "
1354 "now reading on event fd");
1356 /* server has sent us an event. process the
1357 * event and reply */
1359 if (read (client->event_fd, &event, sizeof (event))
1360 != sizeof (event)) {
1361 jack_error ("cannot read server event (%s)",
1362 strerror (errno));
1363 return -1;
1366 status = 0;
1368 switch (event.type) {
1369 case PortRegistered:
1370 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
1371 port = node->data;
1372 if (port->shared->id == event.x.port_id) { // Found port, update port type
1373 port->type_info = &client->engine->port_types[port->shared->ptype_id];
1376 if (control->port_register_cbset) {
1377 client->port_register
1378 (event.x.port_id, TRUE,
1379 client->port_register_arg);
1381 break;
1383 case PortUnregistered:
1384 if (control->port_register_cbset) {
1385 client->port_register
1386 (event.x.port_id, FALSE,
1387 client->port_register_arg);
1389 break;
1391 case ClientRegistered:
1392 if (control->client_register_cbset) {
1393 client->client_register
1394 (event.x.name, TRUE,
1395 client->client_register_arg);
1397 break;
1399 case ClientUnregistered:
1400 if (control->client_register_cbset) {
1401 client->client_register
1402 (event.x.name, FALSE,
1403 client->client_register_arg);
1405 break;
1407 case GraphReordered:
1408 status = jack_handle_reorder (client, &event);
1409 break;
1411 case PortConnected:
1412 case PortDisconnected:
1413 status = jack_client_handle_port_connection
1414 (client, &event);
1415 break;
1417 case BufferSizeChange:
1418 jack_client_invalidate_port_buffers (client);
1419 if (control->bufsize_cbset) {
1420 status = client->bufsize
1421 (control->nframes,
1422 client->bufsize_arg);
1424 break;
1426 case SampleRateChange:
1427 if (control->srate_cbset) {
1428 status = client->srate
1429 (control->nframes,
1430 client->srate_arg);
1432 break;
1434 case XRun:
1435 if (control->xrun_cbset) {
1436 status = client->xrun
1437 (client->xrun_arg);
1439 break;
1441 case AttachPortSegment:
1442 jack_attach_port_segment (client, event.y.ptid);
1443 break;
1445 case StartFreewheel:
1446 jack_start_freewheel (client);
1447 break;
1449 case StopFreewheel:
1450 jack_stop_freewheel (client);
1451 break;
1454 DEBUG ("client has dealt with the event, writing "
1455 "response on event fd");
1457 if (write (client->event_fd, &status, sizeof (status))
1458 != sizeof (status)) {
1459 jack_error ("cannot send event response to "
1460 "engine (%s)", strerror (errno));
1461 return -1;
1465 return 0;
1468 static int
1469 jack_client_core_wait (jack_client_t* client)
1471 jack_client_control_t *control = client->control;
1473 DEBUG ("client polling on %s", client->pollmax == 2 ?
1474 "event_fd and graph_wait_fd..." :
1475 "event_fd only");
1477 while (1) {
1478 if (poll (client->pollfd, client->pollmax, 1000) < 0) {
1479 if (errno == EINTR) {
1480 continue;
1482 jack_error ("poll failed in client (%s)",
1483 strerror (errno));
1484 return -1;
1487 pthread_testcancel();
1489 #ifndef JACK_USE_MACH_THREADS
1491 /* get an accurate timestamp on waking from poll for a
1492 * process() cycle.
1495 if (client->graph_wait_fd >= 0
1496 && client->pollfd[WAIT_POLL_INDEX].revents & POLLIN) {
1497 control->awake_at = jack_get_microseconds();
1500 DEBUG ("pfd[EVENT].revents = 0x%x pfd[WAIT].revents = 0x%x",
1501 client->pollfd[EVENT_POLL_INDEX].revents,
1502 client->pollfd[WAIT_POLL_INDEX].revents);
1504 if (client->graph_wait_fd >= 0 &&
1505 (client->pollfd[WAIT_POLL_INDEX].revents & ~POLLIN)) {
1507 /* our upstream "wait" connection
1508 closed, which either means that
1509 an intermediate client exited, or
1510 jackd exited, or jackd zombified
1513 we can discover the zombification
1514 via client->control->dead, but
1515 the other two possibilities are
1516 impossible to identify just from
1517 this situation. so we have to
1518 check what we are connected to,
1519 and act accordingly.
1522 if (client->upstream_is_jackd) {
1523 DEBUG ("WE DIE\n");
1524 return 0;
1525 } else {
1526 DEBUG ("WE PUNT\n");
1527 /* don't poll on the wait fd
1528 * again until we get a
1529 * GraphReordered event.
1532 client->graph_wait_fd = -1;
1533 client->pollmax = 1;
1536 #endif
1538 if (jack_client_process_events (client)) {
1539 DEBUG ("event processing failed\n");
1540 return 0;
1543 if (client->graph_wait_fd >= 0 &&
1544 (client->pollfd[WAIT_POLL_INDEX].revents & POLLIN)) {
1545 DEBUG ("time to run process()\n");
1546 break;
1550 if (control->dead || client->pollfd[EVENT_POLL_INDEX].revents & ~POLLIN) {
1551 DEBUG ("client appears dead or event pollfd has error status\n");
1552 return -1;
1555 return 0;
1558 static int
1559 jack_wake_next_client (jack_client_t* client)
1561 struct pollfd pfds[1];
1562 int pret = 0;
1563 char c = 0;
1565 if (write (client->graph_next_fd, &c, sizeof (c))
1566 != sizeof (c)) {
1567 DEBUG("cannot write byte to fd %d", client->graph_next_fd);
1568 jack_error ("cannot continue execution of the "
1569 "processing graph (%s)",
1570 strerror(errno));
1571 return -1;
1574 DEBUG ("client sent message to next stage by %" PRIu64 "",
1575 jack_get_microseconds());
1577 DEBUG("reading cleanup byte from pipe %d\n", client->graph_wait_fd);
1579 /* "upstream client went away? readability is checked in
1580 * jack_client_core_wait(), but that's almost a whole cycle
1581 * before we get here.
1584 if (client->graph_wait_fd >= 0) {
1585 pfds[0].fd = client->graph_wait_fd;
1586 pfds[0].events = POLLIN;
1588 /* 0 timeout, don't actually wait */
1589 pret = poll(pfds, 1, 0);
1592 if (pret > 0 && (pfds[0].revents & POLLIN)) {
1593 if (read (client->graph_wait_fd, &c, sizeof (c))
1594 != sizeof (c)) {
1595 jack_error ("cannot complete execution of the "
1596 "processing graph (%s)", strerror(errno));
1597 return -1;
1599 } else {
1600 DEBUG("cleanup byte from pipe %d not available?\n",
1601 client->graph_wait_fd);
1604 return 0;
1607 static jack_nframes_t
1608 jack_thread_first_wait (jack_client_t* client)
1610 if (jack_client_core_wait (client)) {
1611 return 0;
1613 return client->control->nframes;
1616 jack_nframes_t
1617 jack_thread_wait (jack_client_t* client, int status)
1619 client->control->last_status = status;
1621 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1623 /* housekeeping/cleanup after data processing */
1625 if (status == 0 && client->control->timebase_cb_cbset) {
1626 jack_call_timebase_master (client);
1629 /* end preemption checking */
1630 CHECK_PREEMPTION (client->engine, FALSE);
1632 client->control->finished_at = jack_get_microseconds();
1634 /* wake the next client in the chain (could be the server),
1635 and check if we were killed during the process
1636 cycle.
1639 if (jack_wake_next_client (client)) {
1640 DEBUG("client cannot wake next, or is dead\n");
1641 return 0;
1644 if (status || client->control->dead || !client->engine->engine_ok) {
1645 return 0;
1648 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1650 if (jack_client_core_wait (client)) {
1651 return 0;
1654 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1656 /* Time to do data processing */
1658 client->control->state = Running;
1660 /* begin preemption checking */
1661 CHECK_PREEMPTION (client->engine, TRUE);
1663 if (client->control->sync_cb_cbset)
1664 jack_call_sync_client (client);
1666 return client->control->nframes;
1669 jack_nframes_t jack_cycle_wait (jack_client_t* client)
1671 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1673 if (jack_client_core_wait (client)) {
1674 return 0;
1677 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1679 /* Time to do data processing */
1681 client->control->state = Running;
1683 /* begin preemption checking */
1684 CHECK_PREEMPTION (client->engine, TRUE);
1686 if (client->control->sync_cb_cbset)
1687 jack_call_sync_client (client);
1689 return client->control->nframes;
1692 void jack_cycle_signal(jack_client_t* client, int status)
1694 client->control->last_status = status;
1696 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1698 /* housekeeping/cleanup after data processing */
1700 if (status == 0 && client->control->timebase_cb_cbset) {
1701 jack_call_timebase_master (client);
1704 /* end preemption checking */
1705 CHECK_PREEMPTION (client->engine, FALSE);
1707 client->control->finished_at = jack_get_microseconds();
1709 /* wake the next client in the chain (could be the server),
1710 and check if we were killed during the process
1711 cycle.
1714 if (jack_wake_next_client (client)) {
1715 DEBUG("client cannot wake next, or is dead\n");
1716 jack_client_thread_suicide (client);
1717 /*NOTREACHED*/
1720 if (status || client->control->dead || !client->engine->engine_ok) {
1721 jack_client_thread_suicide (client);
1722 /*NOTREACHED*/
1726 static void
1727 jack_client_thread_aux (void *arg)
1729 jack_client_t *client = (jack_client_t *) arg;
1730 jack_client_control_t *control = client->control;
1732 pthread_mutex_lock (&client_lock);
1733 client->thread_ok = TRUE;
1734 client->thread_id = pthread_self();
1735 pthread_cond_signal (&client_ready);
1736 pthread_mutex_unlock (&client_lock);
1738 control->pid = getpid();
1739 control->pgrp = getpgrp();
1741 DEBUG ("client thread is now running");
1743 if (control->thread_init_cbset) {
1744 DEBUG ("calling client thread init callback");
1745 client->thread_init (client->thread_init_arg);
1748 /* wait for first wakeup from server */
1750 if (jack_thread_first_wait (client) == control->nframes) {
1752 /* now run till we're done */
1754 if (control->process_cbset) {
1756 /* run process callback, then wait... ad-infinitum */
1758 while (1) {
1759 DEBUG("client calls process()");
1760 int status = (client->process (control->nframes,
1761 client->process_arg) ==
1762 control->nframes);
1763 control->state = Finished;
1764 DEBUG("client leaves process(), re-enters wait");
1765 if (!jack_thread_wait (client, status)) {
1766 break;
1768 DEBUG("client done with wait");
1771 } else {
1772 /* no process handling but still need to process events */
1773 while (jack_thread_wait (client, 0) == control->nframes)
1778 jack_client_thread_suicide (client);
1781 static void *
1782 jack_client_thread (void *arg)
1784 jack_client_t *client = (jack_client_t *) arg;
1785 jack_client_control_t *control = client->control;
1787 if (client->control->thread_cb_cbset) {
1789 pthread_mutex_lock (&client_lock);
1790 client->thread_ok = TRUE;
1791 client->thread_id = pthread_self();
1792 pthread_cond_signal (&client_ready);
1793 pthread_mutex_unlock (&client_lock);
1795 control->pid = getpid();
1796 control->pgrp = getpgrp();
1798 client->thread_cb(client->thread_cb_arg);
1799 jack_client_thread_suicide(client);
1800 } else {
1801 jack_client_thread_aux(arg);
1804 /*NOTREACHED*/
1805 return (void *) 0;
1808 #ifdef JACK_USE_MACH_THREADS
1809 /* real-time thread : separated from the normal client thread, it will
1810 * communicate with the server using fast mach RPC mechanism */
1812 static void *
1813 jack_client_process_thread (void *arg)
1815 jack_client_t *client = (jack_client_t *) arg;
1816 jack_client_control_t *control = client->control;
1817 int err = 0;
1819 if (client->control->thread_init_cbset) {
1820 /* this means that the init callback will be called twice -taybin*/
1821 DEBUG ("calling client thread init callback");
1822 client->thread_init (client->thread_init_arg);
1825 client->control->pid = getpid();
1826 DEBUG ("client process thread is now running");
1828 client->rt_thread_ok = TRUE;
1830 while (err == 0) {
1832 if (jack_client_suspend(client) < 0) {
1833 jack_error ("jack_client_process_thread :resume error");
1834 goto zombie;
1837 control->awake_at = jack_get_microseconds();
1839 DEBUG ("client resumed");
1841 control->state = Running;
1843 if (control->sync_cb_cbset)
1844 jack_call_sync_client (client);
1846 if (control->process_cbset) {
1847 if (client->process (control->nframes,
1848 client->process_arg) == 0) {
1849 control->state = Finished;
1851 } else {
1852 control->state = Finished;
1855 if (control->timebase_cb_cbset)
1856 jack_call_timebase_master (client);
1858 control->finished_at = jack_get_microseconds();
1860 DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
1861 control->finished_at,
1862 ((float)(control->finished_at - control->awake_at)));
1864 /* check if we were killed during the process cycle
1865 * (or whatever) */
1867 if (client->control->dead) {
1868 jack_error ("jack_client_process_thread: "
1869 "client->control->dead");
1870 goto zombie;
1873 DEBUG("process cycle fully complete\n");
1877 return (void *) ((intptr_t)err);
1879 zombie:
1881 jack_error ("jack_client_process_thread : zombified");
1883 client->rt_thread_ok = FALSE;
1885 if (client->on_info_shutdown) {
1886 jack_error ("zombified - calling shutdown handler");
1887 client->on_info_shutdown (JackClientZombie, "Zombified", client->on_info_shutdown_arg);
1888 } else if (client->on_shutdown) {
1889 jack_error ("zombified - calling shutdown handler");
1890 client->on_shutdown (client->on_shutdown_arg);
1891 } else {
1892 jack_error ("jack_client_process_thread zombified - exiting from JACK");
1893 /* Need a fix : possibly make client crash if
1894 * zombified without shutdown handler */
1895 jack_client_close_aux (client);
1898 pthread_exit (0);
1899 /*NOTREACHED*/
1900 return 0;
1902 #endif /* JACK_USE_MACH_THREADS */
1904 static int
1905 jack_start_thread (jack_client_t *client)
1907 if (client->engine->real_time) {
1909 #ifdef USE_MLOCK
1910 if (client->engine->do_mlock
1911 && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) {
1912 jack_error ("cannot lock down memory for RT thread "
1913 "(%s)", strerror (errno));
1915 #ifdef ENSURE_MLOCK
1916 return -1;
1917 #endif /* ENSURE_MLOCK */
1920 if (client->engine->do_munlock) {
1921 cleanup_mlock ();
1923 #endif /* USE_MLOCK */
1926 #ifdef JACK_USE_MACH_THREADS
1927 /* Stephane Letz : letz@grame.fr
1928 On MacOSX, the normal thread does not need to be real-time.
1930 if (jack_client_create_thread (client,
1931 &client->thread,
1932 client->engine->client_priority,
1933 FALSE,
1934 jack_client_thread, client)) {
1935 return -1;
1937 #else
1938 if (jack_client_create_thread (client,
1939 &client->thread,
1940 client->engine->client_priority,
1941 client->engine->real_time,
1942 jack_client_thread, client)) {
1943 return -1;
1946 #endif
1948 #ifdef JACK_USE_MACH_THREADS
1950 /* a secondary thread that runs the process callback and uses
1951 ultra-fast Mach primitives for inter-thread signalling.
1953 XXX in a properly structured JACK, there would be no
1954 need for this, because we would have client wake up
1955 methods that encapsulated the underlying mechanism
1956 used.
1960 if (jack_client_create_thread(client,
1961 &client->process_thread,
1962 client->engine->client_priority,
1963 client->engine->real_time,
1964 jack_client_process_thread, client)) {
1965 return -1;
1967 #endif /* JACK_USE_MACH_THREADS */
1969 return 0;
1972 int
1973 jack_activate (jack_client_t *client)
1975 jack_request_t req;
1977 /* we need to scribble on our stack to ensure that its memory
1978 * pages are actually mapped (more important for mlockall(2)
1979 * usage in jack_start_thread())
1982 char buf[JACK_THREAD_STACK_TOUCH];
1983 int i;
1985 for (i = 0; i < JACK_THREAD_STACK_TOUCH; i++) {
1986 buf[i] = (char) (i & 0xff);
1989 if (client->control->type == ClientInternal ||
1990 client->control->type == ClientDriver) {
1991 goto startit;
1994 /* get the pid of the client process to pass it to engine */
1996 client->control->pid = getpid ();
1998 #ifdef USE_CAPABILITIES
2000 if (client->engine->has_capabilities != 0 &&
2001 client->control->pid != 0 && client->engine->real_time != 0) {
2003 /* we need to ask the engine for realtime capabilities
2004 before trying to start the realtime thread
2007 req.type = SetClientCapabilities;
2008 req.x.client_id = client->control->id;
2009 req.x.cap_pid = client->control->pid;
2011 jack_client_deliver_request (client, &req);
2013 if (req.status) {
2015 /* what to do? engine is running realtime, it
2016 is using capabilities and has them
2017 (otherwise we would not get an error
2018 return) but for some reason it could not
2019 give the client the required capabilities.
2020 For now, leave the client so that it
2021 still runs, albeit non-realtime.
2024 jack_error ("could not receive realtime capabilities, "
2025 "client will run non-realtime");
2028 #endif /* USE_CAPABILITIES */
2030 if (client->first_active) {
2032 pthread_mutex_init (&client_lock, NULL);
2033 pthread_cond_init (&client_ready, NULL);
2035 pthread_mutex_lock (&client_lock);
2037 if (jack_start_thread (client)) {
2038 pthread_mutex_unlock (&client_lock);
2039 return -1;
2042 pthread_cond_wait (&client_ready, &client_lock);
2043 pthread_mutex_unlock (&client_lock);
2045 if (!client->thread_ok) {
2046 jack_error ("could not start client thread");
2047 return -1;
2050 client->first_active = FALSE;
2053 startit:
2055 req.type = ActivateClient;
2056 req.x.client_id = client->control->id;
2058 return jack_client_deliver_request (client, &req);
2061 static int
2062 jack_deactivate_aux (jack_client_t *client)
2064 jack_request_t req;
2065 int rc = ESRCH; /* already shut down */
2067 if (client && client->control) { /* not shut down? */
2068 rc = 0;
2069 if (client->control->active) { /* still active? */
2070 req.type = DeactivateClient;
2071 req.x.client_id = client->control->id;
2072 rc = jack_client_deliver_request (client, &req);
2075 return rc;
2078 int
2079 jack_deactivate (jack_client_t *client)
2081 return jack_deactivate_aux(client);
2084 static int
2085 jack_client_close_aux (jack_client_t *client)
2087 JSList *node;
2088 void *status;
2089 int rc;
2091 rc = jack_deactivate_aux (client);
2092 if (rc == ESRCH) { /* already shut down? */
2093 return rc;
2096 if (client->control->type == ClientExternal) {
2098 #if JACK_USE_MACH_THREADS
2099 if (client->rt_thread_ok) {
2100 // MacOSX pthread_cancel not implemented in
2101 // Darwin 5.5, 6.4
2102 mach_port_t machThread =
2103 pthread_mach_thread_np (client->process_thread);
2104 thread_terminate (machThread);
2106 #endif
2108 /* stop the thread that communicates with the jack
2109 * server, only if it was actually running
2112 if (client->thread_ok){
2113 pthread_cancel (client->thread);
2114 pthread_join (client->thread, &status);
2117 if (client->control) {
2118 jack_release_shm (&client->control_shm);
2119 client->control = NULL;
2121 if (client->engine) {
2122 jack_release_shm (&client->engine_shm);
2123 client->engine = NULL;
2126 if (client->port_segment) {
2127 jack_port_type_id_t ptid;
2128 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
2129 jack_release_shm (&client->port_segment[ptid]);
2131 free (client->port_segment);
2132 client->port_segment = NULL;
2135 #ifndef JACK_USE_MACH_THREADS
2136 if (client->graph_wait_fd >= 0) {
2137 close (client->graph_wait_fd);
2140 if (client->graph_next_fd >= 0) {
2141 close (client->graph_next_fd);
2143 #endif
2145 close (client->event_fd);
2147 if (shutdown (client->request_fd, SHUT_RDWR)) {
2148 jack_error ("could not shutdown client request socket");
2151 close (client->request_fd);
2155 for (node = client->ports; node; node = jack_slist_next (node)) {
2156 free (node->data);
2158 jack_slist_free (client->ports);
2159 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
2160 free (node->data);
2162 jack_slist_free (client->ports_ext);
2163 jack_client_free (client);
2164 jack_messagebuffer_exit ();
2166 return rc;
2170 jack_client_close (jack_client_t *client)
2172 return jack_client_close_aux(client);
2175 int
2176 jack_is_realtime (jack_client_t *client)
2178 return client->engine->real_time;
2181 jack_nframes_t
2182 jack_get_buffer_size (jack_client_t *client)
2184 return client->engine->buffer_size;
2188 jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
2190 #ifdef DO_BUFFER_RESIZE
2191 jack_request_t req;
2193 req.type = SetBufferSize;
2194 req.x.nframes = nframes;
2196 return jack_client_deliver_request (client, &req);
2197 #else
2198 return ENOSYS;
2200 #endif /* DO_BUFFER_RESIZE */
2203 int
2204 jack_connect (jack_client_t *client, const char *source_port,
2205 const char *destination_port)
2207 jack_request_t req;
2209 req.type = ConnectPorts;
2211 snprintf (req.x.connect.source_port,
2212 sizeof (req.x.connect.source_port), "%s", source_port);
2213 snprintf (req.x.connect.destination_port,
2214 sizeof (req.x.connect.destination_port),
2215 "%s", destination_port);
2217 return jack_client_deliver_request (client, &req);
2221 jack_port_disconnect (jack_client_t *client, jack_port_t *port)
2223 jack_request_t req;
2225 pthread_mutex_lock (&port->connection_lock);
2227 if (port->connections == NULL) {
2228 pthread_mutex_unlock (&port->connection_lock);
2229 return 0;
2232 pthread_mutex_unlock (&port->connection_lock);
2234 req.type = DisconnectPort;
2235 req.x.port_info.port_id = port->shared->id;
2237 return jack_client_deliver_request (client, &req);
2240 int
2241 jack_disconnect (jack_client_t *client, const char *source_port,
2242 const char *destination_port)
2244 jack_request_t req;
2246 req.type = DisconnectPorts;
2248 snprintf (req.x.connect.source_port,
2249 sizeof (req.x.connect.source_port), "%s", source_port);
2250 snprintf (req.x.connect.destination_port,
2251 sizeof (req.x.connect.destination_port),
2252 "%s", destination_port);
2254 return jack_client_deliver_request (client, &req);
2257 void
2258 jack_set_error_function (void (*func) (const char *))
2260 jack_error_callback = func;
2263 void
2264 jack_set_info_function (void (*func) (const char *))
2266 jack_info_callback = func;
2269 int
2270 jack_set_graph_order_callback (jack_client_t *client,
2271 JackGraphOrderCallback callback, void *arg)
2273 if (client->control->active) {
2274 jack_error ("You cannot set callbacks on an active client.");
2275 return -1;
2277 client->graph_order = callback;
2278 client->graph_order_arg = arg;
2279 client->control->graph_order_cbset = (callback != NULL);
2280 return 0;
2283 int jack_set_xrun_callback (jack_client_t *client,
2284 JackXRunCallback callback, void *arg)
2286 if (client->control->active) {
2287 jack_error ("You cannot set callbacks on an active client.");
2288 return -1;
2291 client->xrun = callback;
2292 client->xrun_arg = arg;
2293 client->control->xrun_cbset = (callback != NULL);
2294 return 0;
2298 jack_set_process_callback (jack_client_t *client,
2299 JackProcessCallback callback, void *arg)
2302 if (client->control->active) {
2303 jack_error ("You cannot set callbacks on an active client.");
2304 return -1;
2307 if (client->control->thread_cb_cbset) {
2308 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
2309 return -1;
2312 client->process_arg = arg;
2313 client->process = callback;
2314 client->control->process_cbset = (callback != NULL);
2315 return 0;
2319 jack_set_thread_init_callback (jack_client_t *client,
2320 JackThreadInitCallback callback, void *arg)
2323 if (client->control->active) {
2324 jack_error ("You cannot set callbacks on an active client.");
2325 return -1;
2327 client->thread_init_arg = arg;
2328 client->thread_init = callback;
2329 client->control->thread_init_cbset = (callback != NULL);
2331 /* make sure that the message buffer thread is initialized too */
2333 jack_messagebuffer_thread_init (callback, arg);
2335 return 0;
2339 jack_set_freewheel_callback (jack_client_t *client,
2340 JackFreewheelCallback callback, void *arg)
2342 if (client->control->active) {
2343 jack_error ("You cannot set callbacks on an active client.");
2344 return -1;
2346 client->freewheel_arg = arg;
2347 client->freewheel_cb = callback;
2348 client->control->freewheel_cb_cbset = (callback != NULL);
2349 return 0;
2353 jack_set_buffer_size_callback (jack_client_t *client,
2354 JackBufferSizeCallback callback, void *arg)
2356 client->bufsize_arg = arg;
2357 client->bufsize = callback;
2358 client->control->bufsize_cbset = (callback != NULL);
2359 return 0;
2363 jack_set_port_registration_callback(jack_client_t *client,
2364 JackPortRegistrationCallback callback,
2365 void *arg)
2367 if (client->control->active) {
2368 jack_error ("You cannot set callbacks on an active client.");
2369 return -1;
2371 client->port_register_arg = arg;
2372 client->port_register = callback;
2373 client->control->port_register_cbset = (callback != NULL);
2374 return 0;
2378 jack_set_port_connect_callback(jack_client_t *client,
2379 JackPortConnectCallback callback,
2380 void *arg)
2382 if (client->control->active) {
2383 jack_error ("You cannot set callbacks on an active client.");
2384 return -1;
2386 client->port_connect_arg = arg;
2387 client->port_connect = callback;
2388 client->control->port_connect_cbset = (callback != NULL);
2389 return 0;
2393 jack_set_client_registration_callback(jack_client_t *client,
2394 JackClientRegistrationCallback callback,
2395 void *arg)
2397 if (client->control->active) {
2398 jack_error ("You cannot set callbacks on an active client.");
2399 return -1;
2401 client->client_register_arg = arg;
2402 client->client_register = callback;
2403 client->control->client_register_cbset = (callback != NULL);
2404 return 0;
2408 jack_set_process_thread(jack_client_t* client, JackThreadCallback callback, void *arg)
2410 if (client->control->active) {
2411 jack_error ("You cannot set callbacks on an active client.");
2412 return -1;
2415 if (client->control->process_cbset) {
2416 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
2417 return -1;
2420 client->thread_cb_arg = arg;
2421 client->thread_cb = callback;
2422 client->control->thread_cb_cbset = (callback != NULL);
2423 return 0;
2427 jack_get_process_done_fd (jack_client_t *client)
2429 return client->graph_next_fd;
2432 void
2433 jack_on_shutdown (jack_client_t *client, void (*function)(void *arg), void *arg)
2435 client->on_shutdown = function;
2436 client->on_shutdown_arg = arg;
2439 void
2440 jack_on_info_shutdown (jack_client_t *client, void (*function)(jack_status_t, const char*, void *arg), void *arg)
2442 client->on_info_shutdown = function;
2443 client->on_info_shutdown_arg = arg;
2446 const char **
2447 jack_get_ports (jack_client_t *client,
2448 const char *port_name_pattern,
2449 const char *type_name_pattern,
2450 unsigned long flags)
2452 jack_control_t *engine;
2453 const char **matching_ports;
2454 unsigned long match_cnt;
2455 jack_port_shared_t *psp;
2456 unsigned long i;
2457 regex_t port_regex;
2458 regex_t type_regex;
2459 int matching;
2461 engine = client->engine;
2463 if (port_name_pattern && port_name_pattern[0]) {
2464 regcomp (&port_regex, port_name_pattern,
2465 REG_EXTENDED|REG_NOSUB);
2467 if (type_name_pattern && type_name_pattern[0]) {
2468 regcomp (&type_regex, type_name_pattern,
2469 REG_EXTENDED|REG_NOSUB);
2472 psp = engine->ports;
2473 match_cnt = 0;
2475 if ((matching_ports = (const char **) malloc (sizeof (char *) * engine->port_max)) == NULL) {
2476 return NULL;
2479 for (i = 0; i < engine->port_max; i++) {
2480 matching = 1;
2482 if (!psp[i].in_use) {
2483 continue;
2486 if (flags) {
2487 if ((psp[i].flags & flags) != flags) {
2488 matching = 0;
2492 if (matching && port_name_pattern && port_name_pattern[0]) {
2493 if (regexec (&port_regex, psp[i].name, 0, NULL, 0)) {
2494 matching = 0;
2498 if (matching && type_name_pattern && type_name_pattern[0]) {
2499 jack_port_type_id_t ptid = psp[i].ptype_id;
2500 if (regexec (&type_regex,
2501 engine->port_types[ptid].type_name,
2502 0, NULL, 0)) {
2503 matching = 0;
2507 if (matching) {
2508 matching_ports[match_cnt++] = psp[i].name;
2511 if (port_name_pattern && port_name_pattern[0]) {
2512 regfree (&port_regex);
2514 if (type_name_pattern && type_name_pattern[0]) {
2515 regfree (&type_regex);
2518 matching_ports[match_cnt] = 0;
2520 if (match_cnt == 0) {
2521 free (matching_ports);
2522 matching_ports = 0;
2525 return matching_ports;
2528 float
2529 jack_cpu_load (jack_client_t *client)
2531 return client->engine->cpu_load;
2534 float
2535 jack_get_xrun_delayed_usecs (jack_client_t *client)
2537 return client->engine->xrun_delayed_usecs;
2540 float
2541 jack_get_max_delayed_usecs (jack_client_t *client)
2543 return client->engine->max_delayed_usecs;
2546 void
2547 jack_reset_max_delayed_usecs (jack_client_t *client)
2549 client->engine->max_delayed_usecs = 0.0f;
2552 pthread_t
2553 jack_client_thread_id (jack_client_t *client)
2555 return client->thread_id;
2559 jack_client_name_size(void)
2561 return JACK_CLIENT_NAME_SIZE;
2565 jack_port_name_size(void)
2567 return JACK_PORT_NAME_SIZE;
2571 jack_port_type_size(void)
2573 return JACK_PORT_TYPE_SIZE;
2576 void
2577 jack_free (void* ptr)
2579 free (ptr);