no more dither when converting from float to 24 bit values - i am not sure how this...
[jack.git] / libjack / client.c
bloba1e8216ac52c54fd732cc4210a45ba0a840dfd2e
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->n_port_types = 0;
304 client->port_segment = NULL;
305 return client;
308 #else
310 jack_client_t *
311 jack_client_alloc ()
313 jack_client_t *client;
315 client = (jack_client_t *) malloc (sizeof (jack_client_t));
316 client->pollfd = (struct pollfd *) malloc (sizeof (struct pollfd) * 2);
317 client->pollmax = 2;
318 client->request_fd = -1;
319 client->event_fd = -1;
320 client->upstream_is_jackd = 0;
321 client->graph_wait_fd = -1;
322 client->graph_next_fd = -1;
323 client->ports = NULL;
324 client->ports_ext = NULL;
325 client->engine = NULL;
326 client->control = NULL;
327 client->thread_ok = FALSE;
328 client->first_active = TRUE;
329 client->on_shutdown = NULL;
330 client->n_port_types = 0;
331 client->port_segment = NULL;
333 #ifdef USE_DYNSIMD
334 init_cpu();
335 #endif /* USE_DYNSIMD */
337 return client;
340 #endif
343 * Build the jack_client_t structure for an internal client.
345 jack_client_t *
346 jack_client_alloc_internal (jack_client_control_t *cc, jack_engine_t* engine)
348 jack_client_t* client;
350 client = jack_client_alloc ();
352 client->control = cc;
353 client->engine = engine->control;
355 client->n_port_types = client->engine->n_port_types;
356 client->port_segment = &engine->port_segment[0];
358 return client;
361 static void
362 jack_client_free (jack_client_t *client)
364 if (client->pollfd) {
365 free (client->pollfd);
368 free (client);
371 void
372 jack_client_invalidate_port_buffers (jack_client_t *client)
374 JSList *node;
375 jack_port_t *port;
377 /* This releases all local memory owned by input ports
378 and sets the buffer pointer to NULL. This will cause
379 jack_port_get_buffer() to reallocate space for the
380 buffer on the next call (if there is one).
383 for (node = client->ports; node; node = jack_slist_next (node)) {
384 port = (jack_port_t *) node->data;
386 if (port->shared->flags & JackPortIsInput) {
387 if (port->mix_buffer) {
388 jack_pool_release (port->mix_buffer);
389 port->mix_buffer = NULL;
396 jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)
398 jack_port_t *control_port;
399 jack_port_t *other = 0;
400 JSList *node;
401 int need_free = FALSE;
403 if (client->engine->ports[event->x.self_id].client_id == client->control->id ||
404 client->engine->ports[event->y.other_id].client_id == client->control->id) {
406 /* its one of ours */
408 switch (event->type) {
409 case PortConnected:
410 other = jack_port_new (client, event->y.other_id,
411 client->engine);
412 /* jack_port_by_id_int() always returns an internal
413 * port that does not need to be deallocated
415 control_port = jack_port_by_id_int (client, event->x.self_id,
416 &need_free);
417 pthread_mutex_lock (&control_port->connection_lock);
418 control_port->connections =
419 jack_slist_prepend (control_port->connections,
420 (void *) other);
421 pthread_mutex_unlock (&control_port->connection_lock);
422 break;
424 case PortDisconnected:
425 /* jack_port_by_id_int() always returns an internal
426 * port that does not need to be deallocated
428 control_port = jack_port_by_id_int (client, event->x.self_id,
429 &need_free);
430 pthread_mutex_lock (&control_port->connection_lock);
432 for (node = control_port->connections; node;
433 node = jack_slist_next (node)) {
435 other = (jack_port_t *) node->data;
437 if (other->shared->id == event->y.other_id) {
438 control_port->connections =
439 jack_slist_remove_link (
440 control_port->connections,
441 node);
442 jack_slist_free_1 (node);
443 free (other);
444 break;
448 pthread_mutex_unlock (&control_port->connection_lock);
449 break;
451 default:
452 /* impossible */
453 break;
457 if (client->control->port_connect_cbset) {
458 client->port_connect (event->x.self_id, event->y.other_id,
459 (event->type == PortConnected ? 1 : 0),
460 client->port_connect_arg);
463 return 0;
466 #if JACK_USE_MACH_THREADS
468 static int
469 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
471 client->pollmax = 1;
473 /* If the client registered its own callback for graph order events,
474 execute it now.
477 if (client->control->graph_order) {
478 client->control->graph_order (client->control->graph_order_arg);
481 return 0;
484 #else
486 static int
487 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
489 char path[PATH_MAX+1];
491 DEBUG ("graph reorder\n");
493 if (client->graph_wait_fd >= 0) {
494 DEBUG ("closing graph_wait_fd==%d", client->graph_wait_fd);
495 close (client->graph_wait_fd);
496 client->graph_wait_fd = -1;
499 if (client->graph_next_fd >= 0) {
500 DEBUG ("closing graph_next_fd==%d", client->graph_next_fd);
501 close (client->graph_next_fd);
502 client->graph_next_fd = -1;
505 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n);
507 if ((client->graph_wait_fd = open (path, O_RDONLY|O_NONBLOCK)) < 0) {
508 jack_error ("cannot open specified fifo [%s] for reading (%s)",
509 path, strerror (errno));
510 return -1;
512 DEBUG ("opened new graph_wait_fd %d (%s)", client->graph_wait_fd, path);
514 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n+1);
516 if ((client->graph_next_fd = open (path, O_WRONLY|O_NONBLOCK)) < 0) {
517 jack_error ("cannot open specified fifo [%s] for writing (%s)",
518 path, strerror (errno));
519 return -1;
522 client->upstream_is_jackd = event->y.n;
523 client->pollmax = 2;
525 DEBUG ("opened new graph_next_fd %d (%s) (upstream is jackd? %d)",
526 client->graph_next_fd, path,
527 client->upstream_is_jackd);
529 /* If the client registered its own callback for graph order events,
530 execute it now.
533 if (client->control->graph_order_cbset) {
534 client->graph_order (client->graph_order_arg);
537 return 0;
540 #endif
542 static int
543 server_connect (const char *server_name)
545 int fd;
546 struct sockaddr_un addr;
547 int which = 0;
549 char server_dir[PATH_MAX+1] = "";
551 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
552 jack_error ("cannot create client socket (%s)",
553 strerror (errno));
554 return -1;
557 //JOQ: temporary debug message
558 //jack_info ("DEBUG: connecting to `%s' server", server_name);
560 addr.sun_family = AF_UNIX;
561 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_%d",
562 jack_server_dir (server_name, server_dir) , which);
564 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
565 close (fd);
566 return -1;
569 return fd;
572 static int
573 server_event_connect (jack_client_t *client, const char *server_name)
575 int fd;
576 struct sockaddr_un addr;
577 jack_client_connect_ack_request_t req;
578 jack_client_connect_ack_result_t res;
580 char server_dir[PATH_MAX+1] = "";
582 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
583 jack_error ("cannot create client event socket (%s)",
584 strerror (errno));
585 return -1;
588 addr.sun_family = AF_UNIX;
589 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_ack_0",
590 jack_server_dir (server_name,server_dir));
592 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
593 jack_error ("cannot connect to jack server for events",
594 strerror (errno));
595 close (fd);
596 return -1;
599 req.client_id = client->control->id;
601 if (write (fd, &req, sizeof (req)) != sizeof (req)) {
602 jack_error ("cannot write event connect request to server (%s)",
603 strerror (errno));
604 close (fd);
605 return -1;
608 if (read (fd, &res, sizeof (res)) != sizeof (res)) {
609 jack_error ("cannot read event connect result from server (%s)",
610 strerror (errno));
611 close (fd);
612 return -1;
615 if (res.status != 0) {
616 jack_error ("cannot connect to server for event stream (%s)",
617 strerror (errno));
618 close (fd);
619 return -1;
622 return fd;
625 /* Exec the JACK server in this process. Does not return. */
626 static void
627 _start_server (const char *server_name)
629 FILE* fp = 0;
630 char filename[255];
631 char arguments[255];
632 char buffer[255];
633 char* command = 0;
634 size_t pos = 0;
635 size_t result = 0;
636 char** argv = 0;
637 int i = 0;
638 int good = 0;
639 int ret;
641 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
642 fp = fopen(filename, "r");
644 if (!fp) {
645 fp = fopen("/etc/jackdrc", "r");
647 /* if still not found, check old config name for backwards compatability */
648 if (!fp) {
649 fp = fopen("/etc/jackd.conf", "r");
652 if (fp) {
653 arguments[0] = '\0';
654 ret = fscanf(fp, "%s", buffer);
655 while(ret != 0 && ret != EOF) {
656 strcat(arguments, buffer);
657 strcat(arguments, " ");
658 ret = fscanf(fp, "%s", buffer);
660 if (strlen(arguments) > 0) {
661 good = 1;
665 if (!good) {
666 #if defined(USE_CAPABILITIES)
667 command = JACK_LOCATION "/jackstart";
668 strncpy(arguments, JACK_LOCATION "/jackstart -T -R -d "
669 JACK_DEFAULT_DRIVER " -p 512", 255);
670 #else /* !USE_CAPABILITIES */
671 command = JACK_LOCATION "/jackd";
672 strncpy(arguments, JACK_LOCATION "/jackd -T -d "
673 JACK_DEFAULT_DRIVER, 255);
674 #endif /* USE_CAPABILITIES */
675 } else {
676 result = strcspn(arguments, " ");
677 command = (char *) malloc(result+1);
678 strncpy(command, arguments, result);
679 command[result] = '\0';
682 argv = (char **) malloc (255);
684 while(1) {
685 /* insert -T and -nserver_name in front of arguments */
686 if (i == 1) {
687 argv[i] = (char *) malloc(strlen ("-T") + 1);
688 strcpy (argv[i++], "-T");
689 if (server_name) {
690 size_t optlen = strlen ("-n");
691 char *buf =
692 malloc (optlen
693 + strlen (server_name) + 1);
694 strcpy (buf, "-n");
695 strcpy (buf+optlen, server_name);
696 argv[i++] = buf;
700 result = strcspn(arguments+pos, " ");
701 if (result == 0) {
702 break;
704 argv[i] = (char*)malloc(result+1);
706 strncpy(argv[i], arguments+pos, result);
707 argv[i][result] = '\0';
709 pos += result+1;
710 ++i;
712 argv[i] = 0;
714 #if 0
715 fprintf (stderr, "execing JACK using %s\n", command);
716 for (_xx = 0; argv[_xx]; ++_xx) {
717 fprintf (stderr, "\targv[%d] = %s\n", _xx, argv[_xx]);
719 #endif
721 execv (command, argv);
723 /* If execv() succeeds, it does not return. There's no point
724 * in calling jack_error() here in the child process. */
725 fprintf (stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror (errno));
729 start_server (const char *server_name, jack_options_t options)
731 if ((options & JackNoStartServer)
732 || getenv("JACK_NO_START_SERVER")) {
733 return 1;
736 /* The double fork() forces the server to become a child of
737 * init, which will always clean up zombie process state on
738 * termination. This even works in cases where the server
739 * terminates but this client does not.
741 * Since fork() is usually implemented using copy-on-write
742 * virtual memory tricks, the overhead of the second fork() is
743 * probably relatively small.
745 switch (fork()) {
746 case 0: /* child process */
747 switch (fork()) {
748 case 0: /* grandchild process */
749 _start_server(server_name);
750 _exit (99); /* exec failed */
751 case -1:
752 _exit (98);
753 default:
754 _exit (0);
756 case -1: /* fork() error */
757 return 1; /* failed to start server */
760 /* only the original parent process goes here */
761 return 0; /* (probably) successful */
764 static int
765 jack_request_client (ClientType type,
766 const char* client_name, jack_options_t options,
767 jack_status_t *status, jack_varargs_t *va,
768 jack_client_connect_result_t *res, int *req_fd)
770 jack_client_connect_request_t req;
772 *req_fd = -1;
773 memset (&req, 0, sizeof (req));
774 req.options = options;
776 if (strlen (client_name) >= sizeof (req.name)) {
777 jack_error ("\"%s\" is too long to be used as a JACK client"
778 " name.\n"
779 "Please use %lu characters or less.",
780 client_name, sizeof (req.name));
781 return -1;
784 if (va->load_name
785 && (strlen (va->load_name) > sizeof (req.object_path) - 1)) {
786 jack_error ("\"%s\" is too long to be used as a JACK shared"
787 " object name.\n"
788 "Please use %lu characters or less.",
789 va->load_name, sizeof (req.object_path) - 1);
790 return -1;
793 if (va->load_init
794 && (strlen (va->load_init) > sizeof (req.object_data) - 1)) {
795 jack_error ("\"%s\" is too long to be used as a JACK shared"
796 " object data string.\n"
797 "Please use %lu characters or less.",
798 va->load_init, sizeof (req.object_data) - 1);
799 return -1;
802 if ((*req_fd = server_connect (va->server_name)) < 0) {
803 int trys;
804 if (start_server(va->server_name, options)) {
805 *status |= (JackFailure|JackServerFailed);
806 goto fail;
808 trys = 5;
809 do {
810 sleep(1);
811 if (--trys < 0) {
812 *status |= (JackFailure|JackServerFailed);
813 goto fail;
815 } while ((*req_fd = server_connect (va->server_name)) < 0);
816 *status |= JackServerStarted;
819 /* format connection request */
821 req.protocol_v = jack_protocol_version;
822 req.load = TRUE;
823 req.type = type;
824 snprintf (req.name, sizeof (req.name),
825 "%s", client_name);
826 snprintf (req.object_path, sizeof (req.object_path),
827 "%s", va->load_name);
828 snprintf (req.object_data, sizeof (req.object_data),
829 "%s", va->load_init);
831 if (write (*req_fd, &req, sizeof (req)) != sizeof (req)) {
832 jack_error ("cannot send request to jack server (%s)",
833 strerror (errno));
834 *status |= (JackFailure|JackServerError);
835 goto fail;
838 if (read (*req_fd, res, sizeof (*res)) != sizeof (*res)) {
840 if (errno == 0) {
841 /* server shut the socket */
842 jack_error ("could not attach as client");
843 *status |= (JackFailure|JackServerError);
844 goto fail;
847 if (errno == ECONNRESET) {
848 jack_error ("could not attach as JACK client "
849 "(server has exited)");
850 *status |= (JackFailure|JackServerError);
851 goto fail;
854 jack_error ("cannot read response from jack server (%s)",
855 strerror (errno));
856 *status |= (JackFailure|JackServerError);
857 goto fail;
860 *status |= res->status; /* return server status bits */
862 if (*status & JackFailure) {
863 if (*status & JackVersionError) {
864 jack_error ("client linked with incompatible libjack"
865 " version.");
867 jack_error ("could not attach to JACK server");
868 *status |= JackServerError;
869 goto fail;
872 switch (type) {
873 case ClientDriver:
874 case ClientInternal:
875 close (*req_fd);
876 *req_fd = -1;
877 break;
879 default:
880 break;
883 return 0;
885 fail:
886 if (*req_fd >= 0) {
887 close (*req_fd);
888 *req_fd = -1;
890 return -1;
894 jack_attach_port_segment (jack_client_t *client, jack_port_type_id_t ptid)
896 /* Lookup, attach and register the port/buffer segments in use
897 * right now.
900 if (client->control->type != ClientExternal) {
901 jack_error("Only external clients need attach port segments");
902 abort();
905 /* make sure we have space to store the port
906 segment information.
909 if (ptid >= client->n_port_types) {
911 client->port_segment = (jack_shm_info_t*)
912 realloc (client->port_segment,
913 sizeof (jack_shm_info_t) * (ptid+1));
915 memset (&client->port_segment[client->n_port_types],
917 sizeof (jack_shm_info_t) *
918 (ptid - client->n_port_types));
920 client->n_port_types = ptid + 1;
922 } else {
924 /* release any previous segment */
925 jack_release_shm (&client->port_segment[ptid]);
928 /* get the index into the shm registry */
930 client->port_segment[ptid].index =
931 client->engine->port_types[ptid].shm_registry_index;
933 /* attach the relevant segment */
935 if (jack_attach_shm (&client->port_segment[ptid])) {
936 jack_error ("cannot attach port segment shared memory"
937 " (%s)", strerror (errno));
938 return -1;
941 return 0;
944 jack_client_t *
945 jack_client_open_aux (const char *client_name,
946 jack_options_t options,
947 jack_status_t *status, va_list ap)
949 /* optional arguments: */
950 jack_varargs_t va; /* variable arguments */
952 int req_fd = -1;
953 int ev_fd = -1;
954 jack_client_connect_result_t res;
955 jack_client_t *client;
956 jack_port_type_id_t ptid;
957 jack_status_t my_status;
959 jack_messagebuffer_init ();
961 if (status == NULL) /* no status from caller? */
962 status = &my_status; /* use local status word */
963 *status = 0;
965 /* validate parameters */
966 if ((options & ~JackOpenOptions)) {
967 *status |= (JackFailure|JackInvalidOption);
968 return NULL;
971 /* parse variable arguments */
972 if (ap)
973 jack_varargs_parse(options, ap, &va);
974 else
975 jack_varargs_init(&va);
977 /* External clients need to know where the tmpdir used for
978 communication with the server lives
980 if (jack_get_tmpdir ()) {
981 *status |= JackFailure;
982 return NULL;
985 /* External clients need this initialized. It is already set
986 * up in the server's address space for internal clients.
988 jack_init_time ();
990 if (jack_request_client (ClientExternal, client_name, options, status,
991 &va, &res, &req_fd)) {
992 return NULL;
995 /* Allocate the jack_client_t structure in local memory.
996 * Shared memory is not accessible yet. */
997 client = jack_client_alloc ();
998 strcpy (client->name, res.name);
999 strcpy (client->fifo_prefix, res.fifo_prefix);
1000 client->request_fd = req_fd;
1001 client->pollfd[EVENT_POLL_INDEX].events =
1002 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1003 #ifndef JACK_USE_MACH_THREADS
1004 client->pollfd[WAIT_POLL_INDEX].events =
1005 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1006 #endif
1008 /* Don't access shared memory until server connected. */
1009 if (jack_initialize_shm (va.server_name)) {
1010 jack_error ("Unable to initialize shared memory.");
1011 *status |= (JackFailure|JackShmFailure);
1012 goto fail;
1015 /* attach the engine control/info block */
1016 client->engine_shm.index = res.engine_shm_index;
1017 if (jack_attach_shm (&client->engine_shm)) {
1018 jack_error ("cannot attached engine control shared memory"
1019 " segment");
1020 goto fail;
1023 client->engine = (jack_control_t *) jack_shm_addr (&client->engine_shm);
1025 /* initialize clock source as early as possible */
1026 jack_set_clock_source (client->engine->clock_source);
1028 /* now attach the client control block */
1029 client->control_shm.index = res.client_shm_index;
1030 if (jack_attach_shm (&client->control_shm)) {
1031 jack_error ("cannot attached client control shared memory"
1032 " segment");
1033 goto fail;
1036 client->control = (jack_client_control_t *)
1037 jack_shm_addr (&client->control_shm);
1039 /* Nobody else needs to access this shared memory any more, so
1040 * destroy it. Because we have it attached, it won't vanish
1041 * till we exit (and release it).
1043 jack_destroy_shm (&client->control_shm);
1045 client->n_port_types = client->engine->n_port_types;
1046 client->port_segment = (jack_shm_info_t *)
1047 malloc (sizeof (jack_shm_info_t) * client->n_port_types);
1049 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
1050 client->port_segment[ptid].index =
1051 client->engine->port_types[ptid].shm_registry_index;
1052 client->port_segment[ptid].attached_at = MAP_FAILED;
1053 jack_attach_port_segment (client, ptid);
1056 /* set up the client so that it does the right thing for an
1057 * external client
1059 client->deliver_request = oop_client_deliver_request;
1060 client->deliver_arg = client;
1062 if ((ev_fd = server_event_connect (client, va.server_name)) < 0) {
1063 goto fail;
1066 client->event_fd = ev_fd;
1068 #ifdef JACK_USE_MACH_THREADS
1069 /* specific resources for server/client real-time thread
1070 * communication */
1071 client->clienttask = mach_task_self();
1073 if (task_get_bootstrap_port(client->clienttask, &client->bp)){
1074 jack_error ("Can't find bootstrap port");
1075 goto fail;
1078 if (allocate_mach_clientport(client, res.portnum) < 0) {
1079 jack_error("Can't allocate mach port");
1080 goto fail;
1082 #endif /* JACK_USE_MACH_THREADS */
1083 return client;
1085 fail:
1086 if (client->engine) {
1087 jack_release_shm (&client->engine_shm);
1088 client->engine = 0;
1090 if (client->control) {
1091 jack_release_shm (&client->control_shm);
1092 client->control = 0;
1094 if (req_fd >= 0) {
1095 close (req_fd);
1097 if (ev_fd >= 0) {
1098 close (ev_fd);
1100 free (client);
1102 return NULL;
1105 jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
1107 va_list ap;
1108 va_start(ap, status);
1109 jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
1110 va_end(ap);
1111 return res;
1114 jack_client_t *
1115 jack_client_new (const char *client_name)
1117 jack_options_t options = JackUseExactName;
1118 if (getenv("JACK_START_SERVER") == NULL)
1119 options |= JackNoStartServer;
1120 return jack_client_open_aux (client_name, options, NULL, NULL);
1123 char *
1124 jack_get_client_name (jack_client_t *client)
1126 return client->name;
1130 jack_internal_client_new (const char *client_name,
1131 const char *so_name, const char *so_data)
1133 jack_client_connect_result_t res;
1134 int req_fd;
1135 jack_varargs_t va;
1136 jack_status_t status;
1137 jack_options_t options = JackUseExactName;
1139 if (getenv("JACK_START_SERVER") == NULL)
1140 options |= JackNoStartServer;
1142 jack_varargs_init (&va);
1143 va.load_name = (char *) so_name;
1144 va.load_init = (char *) so_data;
1146 return jack_request_client (ClientInternal, client_name,
1147 options, &status, &va, &res, &req_fd);
1150 char *
1151 jack_default_server_name (void)
1153 char *server_name;
1154 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
1155 server_name = "default";
1156 return server_name;
1159 /* returns the name of the per-user subdirectory of jack_tmpdir */
1160 char *
1161 jack_user_dir (void)
1163 static char user_dir[PATH_MAX+1] = "";
1165 /* format the path name on the first call */
1166 if (user_dir[0] == '\0') {
1167 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
1168 snprintf (user_dir, sizeof (user_dir), "%s/jack",
1169 jack_tmpdir);
1170 } else {
1171 snprintf (user_dir, sizeof (user_dir), "%s/jack-%d",
1172 jack_tmpdir, getuid ());
1176 return user_dir;
1179 /* returns the name of the per-server subdirectory of jack_user_dir() */
1180 char *
1181 jack_server_dir (const char *server_name, char *server_dir)
1183 /* format the path name into the suppled server_dir char array,
1184 * assuming that server_dir is at least as large as PATH_MAX+1 */
1186 snprintf (server_dir, PATH_MAX+1, "%s/%s",
1187 jack_user_dir (), server_name);
1189 return server_dir;
1192 void
1193 jack_internal_client_close (const char *client_name)
1195 jack_client_connect_request_t req;
1196 int fd;
1197 char *server_name = jack_default_server_name ();
1199 req.load = FALSE;
1200 snprintf (req.name, sizeof (req.name), "%s", client_name);
1202 if ((fd = server_connect (server_name)) < 0) {
1203 return;
1206 if (write (fd, &req, sizeof (req)) != sizeof(req)) {
1207 jack_error ("cannot deliver ClientUnload request to JACK "
1208 "server.");
1211 /* no response to this request */
1213 close (fd);
1214 return;
1218 jack_recompute_total_latencies (jack_client_t* client)
1220 jack_request_t request;
1222 request.type = RecomputeTotalLatencies;
1223 return jack_client_deliver_request (client, &request);
1227 jack_recompute_total_latency (jack_client_t* client, jack_port_t* port)
1229 jack_request_t request;
1231 request.type = RecomputeTotalLatency;
1232 request.x.port_info.port_id = port->shared->id;
1233 return jack_client_deliver_request (client, &request);
1237 jack_set_freewheel (jack_client_t* client, int onoff)
1239 jack_request_t request;
1241 request.type = onoff ? FreeWheel : StopFreeWheel;
1242 return jack_client_deliver_request (client, &request);
1245 void
1246 jack_start_freewheel (jack_client_t* client)
1248 jack_client_control_t *control = client->control;
1250 if (client->engine->real_time) {
1251 #if JACK_USE_MACH_THREADS
1252 jack_drop_real_time_scheduling (client->process_thread);
1253 #else
1254 jack_drop_real_time_scheduling (client->thread);
1255 #endif
1258 if (control->freewheel_cb_cbset) {
1259 client->freewheel_cb (1, client->freewheel_arg);
1263 void
1264 jack_stop_freewheel (jack_client_t* client)
1266 jack_client_control_t *control = client->control;
1268 if (client->engine->real_time) {
1269 #if JACK_USE_MACH_THREADS
1270 jack_acquire_real_time_scheduling (client->process_thread,
1271 client->engine->client_priority);
1272 #else
1273 jack_acquire_real_time_scheduling (client->thread,
1274 client->engine->client_priority);
1275 #endif
1278 if (control->freewheel_cb_cbset) {
1279 client->freewheel_cb (0, client->freewheel_arg);
1283 static void
1284 jack_client_thread_suicide (jack_client_t* client)
1286 if (client->on_shutdown) {
1287 jack_error ("zombified - calling shutdown handler");
1288 client->on_shutdown (client->on_shutdown_arg);
1289 } else {
1290 jack_error ("jack_client_thread zombified - exiting from JACK");
1291 jack_client_close_aux (client);
1292 /* Need a fix : possibly make client crash if
1293 * zombified without shutdown handler
1297 pthread_exit (0);
1298 /*NOTREACHED*/
1301 static int
1302 jack_client_process_events (jack_client_t* client)
1304 jack_event_t event;
1305 char status = 0;
1306 jack_client_control_t *control = client->control;
1307 JSList *node;
1308 jack_port_t* port;
1310 DEBUG ("process events");
1312 if (client->pollfd[EVENT_POLL_INDEX].revents & POLLIN) {
1314 DEBUG ("client receives an event, "
1315 "now reading on event fd");
1317 /* server has sent us an event. process the
1318 * event and reply */
1320 if (read (client->event_fd, &event, sizeof (event))
1321 != sizeof (event)) {
1322 jack_error ("cannot read server event (%s)",
1323 strerror (errno));
1324 return -1;
1327 status = 0;
1329 switch (event.type) {
1330 case PortRegistered:
1331 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
1332 port = node->data;
1333 if (port->shared->id == event.x.port_id) { // Found port, update port type
1334 port->type_info = &client->engine->port_types[port->shared->ptype_id];
1337 if (control->port_register_cbset) {
1338 client->port_register
1339 (event.x.port_id, TRUE,
1340 client->port_register_arg);
1342 break;
1344 case PortUnregistered:
1345 if (control->port_register_cbset) {
1346 client->port_register
1347 (event.x.port_id, FALSE,
1348 client->port_register_arg);
1350 break;
1352 case ClientRegistered:
1353 if (control->client_register_cbset) {
1354 client->client_register
1355 (event.x.name, TRUE,
1356 client->client_register_arg);
1358 break;
1360 case ClientUnregistered:
1361 if (control->client_register_cbset) {
1362 client->client_register
1363 (event.x.name, FALSE,
1364 client->client_register_arg);
1366 break;
1368 case GraphReordered:
1369 status = jack_handle_reorder (client, &event);
1370 break;
1372 case PortConnected:
1373 case PortDisconnected:
1374 status = jack_client_handle_port_connection
1375 (client, &event);
1376 break;
1378 case BufferSizeChange:
1379 jack_client_invalidate_port_buffers (client);
1380 if (control->bufsize_cbset) {
1381 status = client->bufsize
1382 (control->nframes,
1383 client->bufsize_arg);
1385 break;
1387 case SampleRateChange:
1388 if (control->srate_cbset) {
1389 status = client->srate
1390 (control->nframes,
1391 client->srate_arg);
1393 break;
1395 case XRun:
1396 if (control->xrun_cbset) {
1397 status = client->xrun
1398 (client->xrun_arg);
1400 break;
1402 case AttachPortSegment:
1403 jack_attach_port_segment (client, event.y.ptid);
1404 break;
1406 case StartFreewheel:
1407 jack_start_freewheel (client);
1408 break;
1410 case StopFreewheel:
1411 jack_stop_freewheel (client);
1412 break;
1415 DEBUG ("client has dealt with the event, writing "
1416 "response on event fd");
1418 if (write (client->event_fd, &status, sizeof (status))
1419 != sizeof (status)) {
1420 jack_error ("cannot send event response to "
1421 "engine (%s)", strerror (errno));
1422 return -1;
1426 return 0;
1429 static int
1430 jack_client_core_wait (jack_client_t* client)
1432 jack_client_control_t *control = client->control;
1434 DEBUG ("client polling on %s", client->pollmax == 2 ?
1435 "event_fd and graph_wait_fd..." :
1436 "event_fd only");
1438 while (1) {
1439 if (poll (client->pollfd, client->pollmax, 1000) < 0) {
1440 if (errno == EINTR) {
1441 continue;
1443 jack_error ("poll failed in client (%s)",
1444 strerror (errno));
1445 return -1;
1448 pthread_testcancel();
1450 #ifndef JACK_USE_MACH_THREADS
1452 /* get an accurate timestamp on waking from poll for a
1453 * process() cycle.
1456 if (client->graph_wait_fd >= 0
1457 && client->pollfd[WAIT_POLL_INDEX].revents & POLLIN) {
1458 control->awake_at = jack_get_microseconds();
1461 DEBUG ("pfd[EVENT].revents = 0x%x pfd[WAIT].revents = 0x%x",
1462 client->pollfd[EVENT_POLL_INDEX].revents,
1463 client->pollfd[WAIT_POLL_INDEX].revents);
1465 if (client->graph_wait_fd >= 0 &&
1466 (client->pollfd[WAIT_POLL_INDEX].revents & ~POLLIN)) {
1468 /* our upstream "wait" connection
1469 closed, which either means that
1470 an intermediate client exited, or
1471 jackd exited, or jackd zombified
1474 we can discover the zombification
1475 via client->control->dead, but
1476 the other two possibilities are
1477 impossible to identify just from
1478 this situation. so we have to
1479 check what we are connected to,
1480 and act accordingly.
1483 if (client->upstream_is_jackd) {
1484 DEBUG ("WE DIE\n");
1485 return 0;
1486 } else {
1487 DEBUG ("WE PUNT\n");
1488 /* don't poll on the wait fd
1489 * again until we get a
1490 * GraphReordered event.
1493 client->graph_wait_fd = -1;
1494 client->pollmax = 1;
1497 #endif
1499 if (jack_client_process_events (client)) {
1500 DEBUG ("event processing failed\n");
1501 return 0;
1504 if (client->graph_wait_fd >= 0 &&
1505 (client->pollfd[WAIT_POLL_INDEX].revents & POLLIN)) {
1506 DEBUG ("time to run process()\n");
1507 break;
1511 if (client->control->dead || client->pollfd[EVENT_POLL_INDEX].revents & ~POLLIN) {
1512 DEBUG ("client appears dead or event pollfd has error status\n");
1513 return -1;
1516 return 0;
1519 static int
1520 jack_wake_next_client (jack_client_t* client)
1522 struct pollfd pfds[1];
1523 int pret = 0;
1524 char c = 0;
1526 if (write (client->graph_next_fd, &c, sizeof (c))
1527 != sizeof (c)) {
1528 DEBUG("cannot write byte to fd %d", client->graph_next_fd);
1529 jack_error ("cannot continue execution of the "
1530 "processing graph (%s)",
1531 strerror(errno));
1532 return -1;
1535 DEBUG ("client sent message to next stage by %" PRIu64 "",
1536 jack_get_microseconds());
1538 DEBUG("reading cleanup byte from pipe %d\n", client->graph_wait_fd);
1540 /* "upstream client went away? readability is checked in
1541 * jack_client_core_wait(), but that's almost a whole cycle
1542 * before we get here.
1545 if (client->graph_wait_fd >= 0) {
1546 pfds[0].fd = client->graph_wait_fd;
1547 pfds[0].events = POLLIN;
1549 /* 0 timeout, don't actually wait */
1550 pret = poll(pfds, 1, 0);
1553 if (pret > 0 && (pfds[0].revents & POLLIN)) {
1554 if (read (client->graph_wait_fd, &c, sizeof (c))
1555 != sizeof (c)) {
1556 jack_error ("cannot complete execution of the "
1557 "processing graph (%s)", strerror(errno));
1558 return -1;
1560 } else {
1561 DEBUG("cleanup byte from pipe %d not available?\n",
1562 client->graph_wait_fd);
1565 return 0;
1568 static jack_nframes_t
1569 jack_thread_first_wait (jack_client_t* client)
1571 if (jack_client_core_wait (client)) {
1572 return 0;
1574 return client->control->nframes;
1577 jack_nframes_t
1578 jack_thread_wait (jack_client_t* client, int status)
1580 client->control->last_status = status;
1582 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1584 /* housekeeping/cleanup after data processing */
1586 if (status == 0 && client->control->timebase_cb_cbset) {
1587 jack_call_timebase_master (client);
1590 /* end preemption checking */
1591 CHECK_PREEMPTION (client->engine, FALSE);
1593 client->control->finished_at = jack_get_microseconds();
1595 /* wake the next client in the chain (could be the server),
1596 and check if we were killed during the process
1597 cycle.
1600 if (jack_wake_next_client (client)) {
1601 DEBUG("client cannot wake next, or is dead\n");
1602 return 0;
1605 if (status || client->control->dead || !client->engine->engine_ok) {
1606 return 0;
1609 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1611 if (jack_client_core_wait (client)) {
1612 return 0;
1615 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1617 /* Time to do data processing */
1619 client->control->state = Running;
1621 /* begin preemption checking */
1622 CHECK_PREEMPTION (client->engine, TRUE);
1624 if (client->control->sync_cb_cbset)
1625 jack_call_sync_client (client);
1627 return client->control->nframes;
1630 jack_nframes_t jack_cycle_wait (jack_client_t* client)
1632 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1634 if (jack_client_core_wait (client)) {
1635 return 0;
1638 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1640 /* Time to do data processing */
1642 client->control->state = Running;
1644 /* begin preemption checking */
1645 CHECK_PREEMPTION (client->engine, TRUE);
1647 if (client->control->sync_cb_cbset)
1648 jack_call_sync_client (client);
1650 return client->control->nframes;
1653 void jack_cycle_signal(jack_client_t* client, int status)
1655 client->control->last_status = status;
1657 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1659 /* housekeeping/cleanup after data processing */
1661 if (status == 0 && client->control->timebase_cb_cbset) {
1662 jack_call_timebase_master (client);
1665 /* end preemption checking */
1666 CHECK_PREEMPTION (client->engine, FALSE);
1668 client->control->finished_at = jack_get_microseconds();
1670 /* wake the next client in the chain (could be the server),
1671 and check if we were killed during the process
1672 cycle.
1675 if (jack_wake_next_client (client)) {
1676 DEBUG("client cannot wake next, or is dead\n");
1677 jack_client_thread_suicide (client);
1678 /*NOTREACHED*/
1681 if (status || client->control->dead || !client->engine->engine_ok) {
1682 jack_client_thread_suicide (client);
1683 /*NOTREACHED*/
1687 static void
1688 jack_client_thread_aux (void *arg)
1690 jack_client_t *client = (jack_client_t *) arg;
1691 jack_client_control_t *control = client->control;
1693 pthread_mutex_lock (&client_lock);
1694 client->thread_ok = TRUE;
1695 client->thread_id = pthread_self();
1696 pthread_cond_signal (&client_ready);
1697 pthread_mutex_unlock (&client_lock);
1699 control->pid = getpid();
1700 control->pgrp = getpgrp();
1702 DEBUG ("client thread is now running");
1704 if (control->thread_init_cbset) {
1705 DEBUG ("calling client thread init callback");
1706 client->thread_init (client->thread_init_arg);
1709 /* wait for first wakeup from server */
1711 if (jack_thread_first_wait (client) == control->nframes) {
1713 /* now run till we're done */
1715 if (control->process_cbset) {
1717 /* run process callback, then wait... ad-infinitum */
1719 while (1) {
1720 DEBUG("client calls process()");
1721 int status = (client->process (control->nframes,
1722 client->process_arg) ==
1723 control->nframes);
1724 control->state = Finished;
1725 DEBUG("client leaves process(), re-enters wait");
1726 if (!jack_thread_wait (client, status)) {
1727 break;
1729 DEBUG("client done with wait");
1732 } else {
1733 /* no process handling but still need to process events */
1734 while (jack_thread_wait (client, 0) == control->nframes)
1739 jack_client_thread_suicide (client);
1742 static void *
1743 jack_client_thread (void *arg)
1745 jack_client_t *client = (jack_client_t *) arg;
1746 jack_client_control_t *control = client->control;
1748 if (client->control->thread_cb_cbset) {
1750 pthread_mutex_lock (&client_lock);
1751 client->thread_ok = TRUE;
1752 client->thread_id = pthread_self();
1753 pthread_cond_signal (&client_ready);
1754 pthread_mutex_unlock (&client_lock);
1756 control->pid = getpid();
1757 control->pgrp = getpgrp();
1759 client->thread_cb(client->thread_cb_arg);
1760 jack_client_thread_suicide(client);
1761 } else {
1762 jack_client_thread_aux(arg);
1765 /*NOTREACHED*/
1766 return (void *) 0;
1769 #ifdef JACK_USE_MACH_THREADS
1770 /* real-time thread : separated from the normal client thread, it will
1771 * communicate with the server using fast mach RPC mechanism */
1773 static void *
1774 jack_client_process_thread (void *arg)
1776 jack_client_t *client = (jack_client_t *) arg;
1777 jack_client_control_t *control = client->control;
1778 int err = 0;
1780 if (client->control->thread_init) {
1781 /* this means that the init callback will be called twice -taybin*/
1782 DEBUG ("calling client thread init callback");
1783 client->control->thread_init (client->control->thread_init_arg);
1786 client->control->pid = getpid();
1787 DEBUG ("client process thread is now running");
1789 client->rt_thread_ok = TRUE;
1791 while (err == 0) {
1793 if (jack_client_suspend(client) < 0) {
1794 jack_error ("jack_client_process_thread :resume error");
1795 goto zombie;
1798 control->awake_at = jack_get_microseconds();
1800 DEBUG ("client resumed");
1802 control->state = Running;
1804 if (control->sync_cb)
1805 jack_call_sync_client (client);
1807 if (control->process) {
1808 if (control->process (control->nframes,
1809 control->process_arg) == 0) {
1810 control->state = Finished;
1812 } else {
1813 control->state = Finished;
1816 if (control->timebase_cb)
1817 jack_call_timebase_master (client);
1819 control->finished_at = jack_get_microseconds();
1821 DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
1822 control->finished_at,
1823 ((float)(control->finished_at - control->awake_at)));
1825 /* check if we were killed during the process cycle
1826 * (or whatever) */
1828 if (client->control->dead) {
1829 jack_error ("jack_client_process_thread: "
1830 "client->control->dead");
1831 goto zombie;
1834 DEBUG("process cycle fully complete\n");
1838 return (void *) ((intptr_t)err);
1840 zombie:
1842 jack_error ("jack_client_process_thread : zombified");
1844 client->rt_thread_ok = FALSE;
1846 if (client->on_shutdown) {
1847 jack_error ("zombified - calling shutdown handler");
1848 client->on_shutdown (client->on_shutdown_arg);
1849 } else {
1850 jack_error ("jack_client_process_thread zombified - exiting from JACK");
1851 /* Need a fix : possibly make client crash if
1852 * zombified without shutdown handler */
1853 jack_client_close_aux (client);
1856 pthread_exit (0);
1857 /*NOTREACHED*/
1858 return 0;
1860 #endif /* JACK_USE_MACH_THREADS */
1862 static int
1863 jack_start_thread (jack_client_t *client)
1865 if (client->engine->real_time) {
1867 #ifdef USE_MLOCK
1868 if (client->engine->do_mlock
1869 && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) {
1870 jack_error ("cannot lock down memory for RT thread "
1871 "(%s)", strerror (errno));
1873 #ifdef ENSURE_MLOCK
1874 return -1;
1875 #endif /* ENSURE_MLOCK */
1878 if (client->engine->do_munlock) {
1879 cleanup_mlock ();
1881 #endif /* USE_MLOCK */
1884 #ifdef JACK_USE_MACH_THREADS
1885 /* Stephane Letz : letz@grame.fr
1886 On MacOSX, the normal thread does not need to be real-time.
1888 if (jack_client_create_thread (client,
1889 &client->thread,
1890 client->engine->client_priority,
1891 FALSE,
1892 jack_client_thread, client)) {
1893 return -1;
1895 #else
1896 if (jack_client_create_thread (client,
1897 &client->thread,
1898 client->engine->client_priority,
1899 client->engine->real_time,
1900 jack_client_thread, client)) {
1901 return -1;
1904 #endif
1906 #ifdef JACK_USE_MACH_THREADS
1908 /* a secondary thread that runs the process callback and uses
1909 ultra-fast Mach primitives for inter-thread signalling.
1911 XXX in a properly structured JACK, there would be no
1912 need for this, because we would have client wake up
1913 methods that encapsulated the underlying mechanism
1914 used.
1918 if (jack_client_create_thread(client,
1919 &client->process_thread,
1920 client->engine->client_priority,
1921 client->engine->real_time,
1922 jack_client_process_thread, client)) {
1923 return -1;
1925 #endif /* JACK_USE_MACH_THREADS */
1927 return 0;
1930 int
1931 jack_activate (jack_client_t *client)
1933 jack_request_t req;
1935 /* we need to scribble on our stack to ensure that its memory
1936 * pages are actually mapped (more important for mlockall(2)
1937 * usage in jack_start_thread())
1940 char buf[JACK_THREAD_STACK_TOUCH];
1941 int i;
1943 for (i = 0; i < JACK_THREAD_STACK_TOUCH; i++) {
1944 buf[i] = (char) (i & 0xff);
1947 if (client->control->type == ClientInternal ||
1948 client->control->type == ClientDriver) {
1949 goto startit;
1952 /* get the pid of the client process to pass it to engine */
1954 client->control->pid = getpid ();
1956 #ifdef USE_CAPABILITIES
1958 if (client->engine->has_capabilities != 0 &&
1959 client->control->pid != 0 && client->engine->real_time != 0) {
1961 /* we need to ask the engine for realtime capabilities
1962 before trying to start the realtime thread
1965 req.type = SetClientCapabilities;
1966 req.x.client_id = client->control->id;
1967 req.x.cap_pid = client->control->pid;
1969 jack_client_deliver_request (client, &req);
1971 if (req.status) {
1973 /* what to do? engine is running realtime, it
1974 is using capabilities and has them
1975 (otherwise we would not get an error
1976 return) but for some reason it could not
1977 give the client the required capabilities.
1978 For now, leave the client so that it
1979 still runs, albeit non-realtime.
1982 jack_error ("could not receive realtime capabilities, "
1983 "client will run non-realtime");
1986 #endif /* USE_CAPABILITIES */
1988 if (client->first_active) {
1990 pthread_mutex_init (&client_lock, NULL);
1991 pthread_cond_init (&client_ready, NULL);
1993 pthread_mutex_lock (&client_lock);
1995 if (jack_start_thread (client)) {
1996 pthread_mutex_unlock (&client_lock);
1997 return -1;
2000 pthread_cond_wait (&client_ready, &client_lock);
2001 pthread_mutex_unlock (&client_lock);
2003 if (!client->thread_ok) {
2004 jack_error ("could not start client thread");
2005 return -1;
2008 client->first_active = FALSE;
2011 startit:
2013 req.type = ActivateClient;
2014 req.x.client_id = client->control->id;
2016 return jack_client_deliver_request (client, &req);
2019 static int
2020 jack_deactivate_aux (jack_client_t *client)
2022 jack_request_t req;
2023 int rc = ESRCH; /* already shut down */
2025 if (client && client->control) { /* not shut down? */
2026 rc = 0;
2027 if (client->control->active) { /* still active? */
2028 req.type = DeactivateClient;
2029 req.x.client_id = client->control->id;
2030 rc = jack_client_deliver_request (client, &req);
2033 return rc;
2036 int
2037 jack_deactivate (jack_client_t *client)
2039 return jack_deactivate_aux(client);
2042 static int
2043 jack_client_close_aux (jack_client_t *client)
2045 JSList *node;
2046 void *status;
2047 int rc;
2049 rc = jack_deactivate_aux (client);
2050 if (rc == ESRCH) { /* already shut down? */
2051 return rc;
2054 if (client->control->type == ClientExternal) {
2056 #if JACK_USE_MACH_THREADS
2057 if (client->rt_thread_ok) {
2058 // MacOSX pthread_cancel not implemented in
2059 // Darwin 5.5, 6.4
2060 mach_port_t machThread =
2061 pthread_mach_thread_np (client->process_thread);
2062 thread_terminate (machThread);
2064 #endif
2066 /* stop the thread that communicates with the jack
2067 * server, only if it was actually running
2070 if (client->thread_ok){
2071 pthread_cancel (client->thread);
2072 pthread_join (client->thread, &status);
2075 if (client->control) {
2076 jack_release_shm (&client->control_shm);
2077 client->control = NULL;
2079 if (client->engine) {
2080 jack_release_shm (&client->engine_shm);
2081 client->engine = NULL;
2084 if (client->port_segment) {
2085 jack_port_type_id_t ptid;
2086 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
2087 jack_release_shm (&client->port_segment[ptid]);
2089 free (client->port_segment);
2090 client->port_segment = NULL;
2093 #ifndef JACK_USE_MACH_THREADS
2094 if (client->graph_wait_fd >= 0) {
2095 close (client->graph_wait_fd);
2098 if (client->graph_next_fd >= 0) {
2099 close (client->graph_next_fd);
2101 #endif
2103 close (client->event_fd);
2105 if (shutdown (client->request_fd, SHUT_RDWR)) {
2106 jack_error ("could not shutdown client request socket");
2109 close (client->request_fd);
2113 for (node = client->ports; node; node = jack_slist_next (node)) {
2114 free (node->data);
2116 jack_slist_free (client->ports);
2117 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
2118 free (node->data);
2120 jack_slist_free (client->ports_ext);
2121 jack_client_free (client);
2122 jack_messagebuffer_exit ();
2124 return rc;
2128 jack_client_close (jack_client_t *client)
2130 return jack_client_close_aux(client);
2133 int
2134 jack_is_realtime (jack_client_t *client)
2136 return client->engine->real_time;
2139 jack_nframes_t
2140 jack_get_buffer_size (jack_client_t *client)
2142 return client->engine->buffer_size;
2146 jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
2148 #ifdef DO_BUFFER_RESIZE
2149 jack_request_t req;
2151 req.type = SetBufferSize;
2152 req.x.nframes = nframes;
2154 return jack_client_deliver_request (client, &req);
2155 #else
2156 return ENOSYS;
2158 #endif /* DO_BUFFER_RESIZE */
2161 int
2162 jack_connect (jack_client_t *client, const char *source_port,
2163 const char *destination_port)
2165 jack_request_t req;
2167 req.type = ConnectPorts;
2169 snprintf (req.x.connect.source_port,
2170 sizeof (req.x.connect.source_port), "%s", source_port);
2171 snprintf (req.x.connect.destination_port,
2172 sizeof (req.x.connect.destination_port),
2173 "%s", destination_port);
2175 return jack_client_deliver_request (client, &req);
2179 jack_port_disconnect (jack_client_t *client, jack_port_t *port)
2181 jack_request_t req;
2183 pthread_mutex_lock (&port->connection_lock);
2185 if (port->connections == NULL) {
2186 pthread_mutex_unlock (&port->connection_lock);
2187 return 0;
2190 pthread_mutex_unlock (&port->connection_lock);
2192 req.type = DisconnectPort;
2193 req.x.port_info.port_id = port->shared->id;
2195 return jack_client_deliver_request (client, &req);
2198 int
2199 jack_disconnect (jack_client_t *client, const char *source_port,
2200 const char *destination_port)
2202 jack_request_t req;
2204 req.type = DisconnectPorts;
2206 snprintf (req.x.connect.source_port,
2207 sizeof (req.x.connect.source_port), "%s", source_port);
2208 snprintf (req.x.connect.destination_port,
2209 sizeof (req.x.connect.destination_port),
2210 "%s", destination_port);
2212 return jack_client_deliver_request (client, &req);
2215 void
2216 jack_set_error_function (void (*func) (const char *))
2218 jack_error_callback = func;
2221 void
2222 jack_set_info_function (void (*func) (const char *))
2224 jack_info_callback = func;
2227 int
2228 jack_set_graph_order_callback (jack_client_t *client,
2229 JackGraphOrderCallback callback, void *arg)
2231 if (client->control->active) {
2232 jack_error ("You cannot set callbacks on an active client.");
2233 return -1;
2235 client->graph_order = callback;
2236 client->graph_order_arg = arg;
2237 client->control->graph_order_cbset = (callback != NULL);
2238 return 0;
2241 int jack_set_xrun_callback (jack_client_t *client,
2242 JackXRunCallback callback, void *arg)
2244 if (client->control->active) {
2245 jack_error ("You cannot set callbacks on an active client.");
2246 return -1;
2249 client->xrun = callback;
2250 client->xrun_arg = arg;
2251 client->control->xrun_cbset = (callback != NULL);
2252 return 0;
2256 jack_set_process_callback (jack_client_t *client,
2257 JackProcessCallback callback, void *arg)
2260 if (client->control->active) {
2261 jack_error ("You cannot set callbacks on an active client.");
2262 return -1;
2265 if (client->control->thread_cb_cbset) {
2266 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
2267 return -1;
2270 client->process_arg = arg;
2271 client->process = callback;
2272 client->control->process_cbset = (callback != NULL);
2273 return 0;
2277 jack_set_thread_init_callback (jack_client_t *client,
2278 JackThreadInitCallback callback, void *arg)
2281 if (client->control->active) {
2282 jack_error ("You cannot set callbacks on an active client.");
2283 return -1;
2285 client->thread_init_arg = arg;
2286 client->thread_init = callback;
2287 client->control->thread_init_cbset = (callback != NULL);
2288 return 0;
2292 jack_set_freewheel_callback (jack_client_t *client,
2293 JackFreewheelCallback callback, void *arg)
2295 if (client->control->active) {
2296 jack_error ("You cannot set callbacks on an active client.");
2297 return -1;
2299 client->freewheel_arg = arg;
2300 client->freewheel_cb = callback;
2301 client->control->freewheel_cb_cbset = (callback != NULL);
2302 return 0;
2306 jack_set_buffer_size_callback (jack_client_t *client,
2307 JackBufferSizeCallback callback, void *arg)
2309 client->bufsize_arg = arg;
2310 client->bufsize = callback;
2311 client->control->bufsize_cbset = (callback != NULL);
2312 return 0;
2316 jack_set_port_registration_callback(jack_client_t *client,
2317 JackPortRegistrationCallback callback,
2318 void *arg)
2320 if (client->control->active) {
2321 jack_error ("You cannot set callbacks on an active client.");
2322 return -1;
2324 client->port_register_arg = arg;
2325 client->port_register = callback;
2326 client->control->port_register_cbset = (callback != NULL);
2327 return 0;
2331 jack_set_port_connect_callback(jack_client_t *client,
2332 JackPortConnectCallback 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_connect_arg = arg;
2340 client->port_connect = callback;
2341 client->control->port_connect_cbset = (callback != NULL);
2342 return 0;
2346 jack_set_client_registration_callback(jack_client_t *client,
2347 JackClientRegistrationCallback 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->client_register_arg = arg;
2355 client->client_register = callback;
2356 client->control->client_register_cbset = (callback != NULL);
2357 return 0;
2361 jack_set_process_thread(jack_client_t* client, JackThreadCallback callback, void *arg)
2363 if (client->control->active) {
2364 jack_error ("You cannot set callbacks on an active client.");
2365 return -1;
2368 if (client->control->process_cbset) {
2369 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
2370 return -1;
2373 client->thread_cb_arg = arg;
2374 client->thread_cb = callback;
2375 client->control->thread_cb_cbset = (callback != NULL);
2376 return 0;
2380 jack_get_process_done_fd (jack_client_t *client)
2382 return client->graph_next_fd;
2385 void
2386 jack_on_shutdown (jack_client_t *client, void (*function)(void *arg), void *arg)
2388 client->on_shutdown = function;
2389 client->on_shutdown_arg = arg;
2392 const char **
2393 jack_get_ports (jack_client_t *client,
2394 const char *port_name_pattern,
2395 const char *type_name_pattern,
2396 unsigned long flags)
2398 jack_control_t *engine;
2399 const char **matching_ports;
2400 unsigned long match_cnt;
2401 jack_port_shared_t *psp;
2402 unsigned long i;
2403 regex_t port_regex;
2404 regex_t type_regex;
2405 int matching;
2407 engine = client->engine;
2409 if (port_name_pattern && port_name_pattern[0]) {
2410 regcomp (&port_regex, port_name_pattern,
2411 REG_EXTENDED|REG_NOSUB);
2413 if (type_name_pattern && type_name_pattern[0]) {
2414 regcomp (&type_regex, type_name_pattern,
2415 REG_EXTENDED|REG_NOSUB);
2418 psp = engine->ports;
2419 match_cnt = 0;
2421 matching_ports = (const char **)
2422 malloc (sizeof (char *) * engine->port_max);
2424 for (i = 0; i < engine->port_max; i++) {
2425 matching = 1;
2427 if (!psp[i].in_use) {
2428 continue;
2431 if (flags) {
2432 if ((psp[i].flags & flags) != flags) {
2433 matching = 0;
2437 if (matching && port_name_pattern && port_name_pattern[0]) {
2438 if (regexec (&port_regex, psp[i].name, 0, NULL, 0)) {
2439 matching = 0;
2443 if (matching && type_name_pattern && type_name_pattern[0]) {
2444 jack_port_type_id_t ptid = psp[i].ptype_id;
2445 if (regexec (&type_regex,
2446 engine->port_types[ptid].type_name,
2447 0, NULL, 0)) {
2448 matching = 0;
2452 if (matching) {
2453 matching_ports[match_cnt++] = psp[i].name;
2456 if (port_name_pattern && port_name_pattern[0]) {
2457 regfree (&port_regex);
2459 if (type_name_pattern && type_name_pattern[0]) {
2460 regfree (&type_regex);
2463 matching_ports[match_cnt] = 0;
2465 if (match_cnt == 0) {
2466 free (matching_ports);
2467 matching_ports = 0;
2470 return matching_ports;
2473 float
2474 jack_cpu_load (jack_client_t *client)
2476 return client->engine->cpu_load;
2479 float
2480 jack_get_xrun_delayed_usecs (jack_client_t *client)
2482 return client->engine->xrun_delayed_usecs;
2485 float
2486 jack_get_max_delayed_usecs (jack_client_t *client)
2488 return client->engine->max_delayed_usecs;
2491 void
2492 jack_reset_max_delayed_usecs (jack_client_t *client)
2494 client->engine->max_delayed_usecs = 0.0f;
2497 pthread_t
2498 jack_client_thread_id (jack_client_t *client)
2500 return client->thread_id;
2504 jack_client_name_size(void)
2506 return JACK_CLIENT_NAME_SIZE;
2510 jack_port_name_size(void)
2512 return JACK_PORT_NAME_SIZE;
2516 jack_port_type_size(void)
2518 return JACK_PORT_TYPE_SIZE;