[alsa-out] this seems okish.
[jack.git] / libjack / client.c
blobed0bee89b8d5714129ef97b96eb377d4f8b5ca4f
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;
306 #ifdef USE_DYNSIMD
307 init_cpu();
308 #endif /* USE_DYNSIMD */
310 return client;
313 #else
315 jack_client_t *
316 jack_client_alloc ()
318 jack_client_t *client;
320 client = (jack_client_t *) malloc (sizeof (jack_client_t));
321 client->pollfd = (struct pollfd *) malloc (sizeof (struct pollfd) * 2);
322 client->pollmax = 2;
323 client->request_fd = -1;
324 client->event_fd = -1;
325 client->upstream_is_jackd = 0;
326 client->graph_wait_fd = -1;
327 client->graph_next_fd = -1;
328 client->ports = NULL;
329 client->ports_ext = NULL;
330 client->engine = NULL;
331 client->control = NULL;
332 client->thread_ok = FALSE;
333 client->first_active = TRUE;
334 client->on_shutdown = NULL;
335 client->n_port_types = 0;
336 client->port_segment = NULL;
338 #ifdef USE_DYNSIMD
339 init_cpu();
340 #endif /* USE_DYNSIMD */
342 return client;
345 #endif
348 * Build the jack_client_t structure for an internal client.
350 jack_client_t *
351 jack_client_alloc_internal (jack_client_control_t *cc, jack_engine_t* engine)
353 jack_client_t* client;
355 client = jack_client_alloc ();
357 client->control = cc;
358 client->engine = engine->control;
360 client->n_port_types = client->engine->n_port_types;
361 client->port_segment = &engine->port_segment[0];
363 return client;
366 static void
367 jack_client_free (jack_client_t *client)
369 if (client->pollfd) {
370 free (client->pollfd);
373 free (client);
376 void
377 jack_client_invalidate_port_buffers (jack_client_t *client)
379 JSList *node;
380 jack_port_t *port;
382 /* This releases all local memory owned by input ports
383 and sets the buffer pointer to NULL. This will cause
384 jack_port_get_buffer() to reallocate space for the
385 buffer on the next call (if there is one).
388 for (node = client->ports; node; node = jack_slist_next (node)) {
389 port = (jack_port_t *) node->data;
391 if (port->shared->flags & JackPortIsInput) {
392 if (port->mix_buffer) {
393 jack_pool_release (port->mix_buffer);
394 port->mix_buffer = NULL;
401 jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)
403 jack_port_t *control_port;
404 jack_port_t *other = 0;
405 JSList *node;
406 int need_free = FALSE;
408 if (client->engine->ports[event->x.self_id].client_id == client->control->id ||
409 client->engine->ports[event->y.other_id].client_id == client->control->id) {
411 /* its one of ours */
413 switch (event->type) {
414 case PortConnected:
415 other = jack_port_new (client, event->y.other_id,
416 client->engine);
417 /* jack_port_by_id_int() always returns an internal
418 * port that does not need to be deallocated
420 control_port = jack_port_by_id_int (client, event->x.self_id,
421 &need_free);
422 pthread_mutex_lock (&control_port->connection_lock);
423 control_port->connections =
424 jack_slist_prepend (control_port->connections,
425 (void *) other);
426 pthread_mutex_unlock (&control_port->connection_lock);
427 break;
429 case PortDisconnected:
430 /* jack_port_by_id_int() always returns an internal
431 * port that does not need to be deallocated
433 control_port = jack_port_by_id_int (client, event->x.self_id,
434 &need_free);
435 pthread_mutex_lock (&control_port->connection_lock);
437 for (node = control_port->connections; node;
438 node = jack_slist_next (node)) {
440 other = (jack_port_t *) node->data;
442 if (other->shared->id == event->y.other_id) {
443 control_port->connections =
444 jack_slist_remove_link (
445 control_port->connections,
446 node);
447 jack_slist_free_1 (node);
448 free (other);
449 break;
453 pthread_mutex_unlock (&control_port->connection_lock);
454 break;
456 default:
457 /* impossible */
458 break;
462 if (client->control->port_connect_cbset) {
463 client->port_connect (event->x.self_id, event->y.other_id,
464 (event->type == PortConnected ? 1 : 0),
465 client->port_connect_arg);
468 return 0;
471 #if JACK_USE_MACH_THREADS
473 static int
474 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
476 client->pollmax = 1;
478 /* If the client registered its own callback for graph order events,
479 execute it now.
482 if (client->control->graph_order_cbset) {
483 client->graph_order (client->graph_order_arg);
486 return 0;
489 #else
491 static int
492 jack_handle_reorder (jack_client_t *client, jack_event_t *event)
494 char path[PATH_MAX+1];
496 DEBUG ("graph reorder\n");
498 if (client->graph_wait_fd >= 0) {
499 DEBUG ("closing graph_wait_fd==%d", client->graph_wait_fd);
500 close (client->graph_wait_fd);
501 client->graph_wait_fd = -1;
504 if (client->graph_next_fd >= 0) {
505 DEBUG ("closing graph_next_fd==%d", client->graph_next_fd);
506 close (client->graph_next_fd);
507 client->graph_next_fd = -1;
510 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n);
512 if ((client->graph_wait_fd = open (path, O_RDONLY|O_NONBLOCK)) < 0) {
513 jack_error ("cannot open specified fifo [%s] for reading (%s)",
514 path, strerror (errno));
515 return -1;
517 DEBUG ("opened new graph_wait_fd %d (%s)", client->graph_wait_fd, path);
519 sprintf (path, "%s-%" PRIu32, client->fifo_prefix, event->x.n+1);
521 if ((client->graph_next_fd = open (path, O_WRONLY|O_NONBLOCK)) < 0) {
522 jack_error ("cannot open specified fifo [%s] for writing (%s)",
523 path, strerror (errno));
524 return -1;
527 client->upstream_is_jackd = event->y.n;
528 client->pollmax = 2;
530 DEBUG ("opened new graph_next_fd %d (%s) (upstream is jackd? %d)",
531 client->graph_next_fd, path,
532 client->upstream_is_jackd);
534 /* If the client registered its own callback for graph order events,
535 execute it now.
538 if (client->control->graph_order_cbset) {
539 client->graph_order (client->graph_order_arg);
542 return 0;
545 #endif
547 static int
548 server_connect (const char *server_name)
550 int fd;
551 struct sockaddr_un addr;
552 int which = 0;
554 char server_dir[PATH_MAX+1] = "";
556 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
557 jack_error ("cannot create client socket (%s)",
558 strerror (errno));
559 return -1;
562 //JOQ: temporary debug message
563 //jack_info ("DEBUG: connecting to `%s' server", server_name);
565 addr.sun_family = AF_UNIX;
566 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_%d",
567 jack_server_dir (server_name, server_dir) , which);
569 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
570 close (fd);
571 return -1;
574 return fd;
577 static int
578 server_event_connect (jack_client_t *client, const char *server_name)
580 int fd;
581 struct sockaddr_un addr;
582 jack_client_connect_ack_request_t req;
583 jack_client_connect_ack_result_t res;
585 char server_dir[PATH_MAX+1] = "";
587 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
588 jack_error ("cannot create client event socket (%s)",
589 strerror (errno));
590 return -1;
593 addr.sun_family = AF_UNIX;
594 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_ack_0",
595 jack_server_dir (server_name,server_dir));
597 if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
598 jack_error ("cannot connect to jack server for events",
599 strerror (errno));
600 close (fd);
601 return -1;
604 req.client_id = client->control->id;
606 if (write (fd, &req, sizeof (req)) != sizeof (req)) {
607 jack_error ("cannot write event connect request to server (%s)",
608 strerror (errno));
609 close (fd);
610 return -1;
613 if (read (fd, &res, sizeof (res)) != sizeof (res)) {
614 jack_error ("cannot read event connect result from server (%s)",
615 strerror (errno));
616 close (fd);
617 return -1;
620 if (res.status != 0) {
621 jack_error ("cannot connect to server for event stream (%s)",
622 strerror (errno));
623 close (fd);
624 return -1;
627 return fd;
630 /* Exec the JACK server in this process. Does not return. */
631 static void
632 _start_server (const char *server_name)
634 FILE* fp = 0;
635 char filename[255];
636 char arguments[255];
637 char buffer[255];
638 char* command = 0;
639 size_t pos = 0;
640 size_t result = 0;
641 char** argv = 0;
642 int i = 0;
643 int good = 0;
644 int ret;
646 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
647 fp = fopen(filename, "r");
649 if (!fp) {
650 fp = fopen("/etc/jackdrc", "r");
652 /* if still not found, check old config name for backwards compatability */
653 if (!fp) {
654 fp = fopen("/etc/jackd.conf", "r");
657 if (fp) {
658 arguments[0] = '\0';
659 ret = fscanf(fp, "%s", buffer);
660 while(ret != 0 && ret != EOF) {
661 strcat(arguments, buffer);
662 strcat(arguments, " ");
663 ret = fscanf(fp, "%s", buffer);
665 if (strlen(arguments) > 0) {
666 good = 1;
670 if (!good) {
671 #if defined(USE_CAPABILITIES)
672 command = JACK_LOCATION "/jackstart";
673 strncpy(arguments, JACK_LOCATION "/jackstart -T -R -d "
674 JACK_DEFAULT_DRIVER " -p 512", 255);
675 #else /* !USE_CAPABILITIES */
676 command = JACK_LOCATION "/jackd";
677 strncpy(arguments, JACK_LOCATION "/jackd -T -d "
678 JACK_DEFAULT_DRIVER, 255);
679 #endif /* USE_CAPABILITIES */
680 } else {
681 result = strcspn(arguments, " ");
682 command = (char *) malloc(result+1);
683 strncpy(command, arguments, result);
684 command[result] = '\0';
687 argv = (char **) malloc (255);
689 while(1) {
690 /* insert -T and -nserver_name in front of arguments */
691 if (i == 1) {
692 argv[i] = (char *) malloc(strlen ("-T") + 1);
693 strcpy (argv[i++], "-T");
694 if (server_name) {
695 size_t optlen = strlen ("-n");
696 char *buf =
697 malloc (optlen
698 + strlen (server_name) + 1);
699 strcpy (buf, "-n");
700 strcpy (buf+optlen, server_name);
701 argv[i++] = buf;
705 result = strcspn(arguments+pos, " ");
706 if (result == 0) {
707 break;
709 argv[i] = (char*)malloc(result+1);
711 strncpy(argv[i], arguments+pos, result);
712 argv[i][result] = '\0';
714 pos += result+1;
715 ++i;
717 argv[i] = 0;
719 #if 0
720 fprintf (stderr, "execing JACK using %s\n", command);
721 for (_xx = 0; argv[_xx]; ++_xx) {
722 fprintf (stderr, "\targv[%d] = %s\n", _xx, argv[_xx]);
724 #endif
726 execv (command, argv);
728 /* If execv() succeeds, it does not return. There's no point
729 * in calling jack_error() here in the child process. */
730 fprintf (stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror (errno));
734 start_server (const char *server_name, jack_options_t options)
736 if ((options & JackNoStartServer)
737 || getenv("JACK_NO_START_SERVER")) {
738 return 1;
741 /* The double fork() forces the server to become a child of
742 * init, which will always clean up zombie process state on
743 * termination. This even works in cases where the server
744 * terminates but this client does not.
746 * Since fork() is usually implemented using copy-on-write
747 * virtual memory tricks, the overhead of the second fork() is
748 * probably relatively small.
750 switch (fork()) {
751 case 0: /* child process */
752 switch (fork()) {
753 case 0: /* grandchild process */
754 _start_server(server_name);
755 _exit (99); /* exec failed */
756 case -1:
757 _exit (98);
758 default:
759 _exit (0);
761 case -1: /* fork() error */
762 return 1; /* failed to start server */
765 /* only the original parent process goes here */
766 return 0; /* (probably) successful */
769 static int
770 jack_request_client (ClientType type,
771 const char* client_name, jack_options_t options,
772 jack_status_t *status, jack_varargs_t *va,
773 jack_client_connect_result_t *res, int *req_fd)
775 jack_client_connect_request_t req;
777 *req_fd = -1;
778 memset (&req, 0, sizeof (req));
779 req.options = options;
781 if (strlen (client_name) >= sizeof (req.name)) {
782 jack_error ("\"%s\" is too long to be used as a JACK client"
783 " name.\n"
784 "Please use %lu characters or less.",
785 client_name, sizeof (req.name));
786 return -1;
789 if (va->load_name
790 && (strlen (va->load_name) > sizeof (req.object_path) - 1)) {
791 jack_error ("\"%s\" is too long to be used as a JACK shared"
792 " object name.\n"
793 "Please use %lu characters or less.",
794 va->load_name, sizeof (req.object_path) - 1);
795 return -1;
798 if (va->load_init
799 && (strlen (va->load_init) > sizeof (req.object_data) - 1)) {
800 jack_error ("\"%s\" is too long to be used as a JACK shared"
801 " object data string.\n"
802 "Please use %lu characters or less.",
803 va->load_init, sizeof (req.object_data) - 1);
804 return -1;
807 if ((*req_fd = server_connect (va->server_name)) < 0) {
808 int trys;
809 if (start_server(va->server_name, options)) {
810 *status |= (JackFailure|JackServerFailed);
811 goto fail;
813 trys = 5;
814 do {
815 sleep(1);
816 if (--trys < 0) {
817 *status |= (JackFailure|JackServerFailed);
818 goto fail;
820 } while ((*req_fd = server_connect (va->server_name)) < 0);
821 *status |= JackServerStarted;
824 /* format connection request */
826 req.protocol_v = jack_protocol_version;
827 req.load = TRUE;
828 req.type = type;
829 snprintf (req.name, sizeof (req.name),
830 "%s", client_name);
831 snprintf (req.object_path, sizeof (req.object_path),
832 "%s", va->load_name);
833 snprintf (req.object_data, sizeof (req.object_data),
834 "%s", va->load_init);
836 if (write (*req_fd, &req, sizeof (req)) != sizeof (req)) {
837 jack_error ("cannot send request to jack server (%s)",
838 strerror (errno));
839 *status |= (JackFailure|JackServerError);
840 goto fail;
843 if (read (*req_fd, res, sizeof (*res)) != sizeof (*res)) {
845 if (errno == 0) {
846 /* server shut the socket */
847 jack_error ("could not attach as client");
848 *status |= (JackFailure|JackServerError);
849 goto fail;
852 if (errno == ECONNRESET) {
853 jack_error ("could not attach as JACK client "
854 "(server has exited)");
855 *status |= (JackFailure|JackServerError);
856 goto fail;
859 jack_error ("cannot read response from jack server (%s)",
860 strerror (errno));
861 *status |= (JackFailure|JackServerError);
862 goto fail;
865 *status |= res->status; /* return server status bits */
867 if (*status & JackFailure) {
868 if (*status & JackVersionError) {
869 jack_error ("client linked with incompatible libjack"
870 " version.");
872 jack_error ("could not attach to JACK server");
873 *status |= JackServerError;
874 goto fail;
877 switch (type) {
878 case ClientDriver:
879 case ClientInternal:
880 close (*req_fd);
881 *req_fd = -1;
882 break;
884 default:
885 break;
888 return 0;
890 fail:
891 if (*req_fd >= 0) {
892 close (*req_fd);
893 *req_fd = -1;
895 return -1;
899 jack_attach_port_segment (jack_client_t *client, jack_port_type_id_t ptid)
901 /* Lookup, attach and register the port/buffer segments in use
902 * right now.
905 if (client->control->type != ClientExternal) {
906 jack_error("Only external clients need attach port segments");
907 abort();
910 /* make sure we have space to store the port
911 segment information.
914 if (ptid >= client->n_port_types) {
916 client->port_segment = (jack_shm_info_t*)
917 realloc (client->port_segment,
918 sizeof (jack_shm_info_t) * (ptid+1));
920 memset (&client->port_segment[client->n_port_types],
922 sizeof (jack_shm_info_t) *
923 (ptid - client->n_port_types));
925 client->n_port_types = ptid + 1;
927 } else {
929 /* release any previous segment */
930 jack_release_shm (&client->port_segment[ptid]);
933 /* get the index into the shm registry */
935 client->port_segment[ptid].index =
936 client->engine->port_types[ptid].shm_registry_index;
938 /* attach the relevant segment */
940 if (jack_attach_shm (&client->port_segment[ptid])) {
941 jack_error ("cannot attach port segment shared memory"
942 " (%s)", strerror (errno));
943 return -1;
946 return 0;
949 jack_client_t *
950 jack_client_open_aux (const char *client_name,
951 jack_options_t options,
952 jack_status_t *status, va_list ap)
954 /* optional arguments: */
955 jack_varargs_t va; /* variable arguments */
957 int req_fd = -1;
958 int ev_fd = -1;
959 jack_client_connect_result_t res;
960 jack_client_t *client;
961 jack_port_type_id_t ptid;
962 jack_status_t my_status;
964 jack_messagebuffer_init ();
966 if (status == NULL) /* no status from caller? */
967 status = &my_status; /* use local status word */
968 *status = 0;
970 /* validate parameters */
971 if ((options & ~JackOpenOptions)) {
972 *status |= (JackFailure|JackInvalidOption);
973 return NULL;
976 /* parse variable arguments */
977 jack_varargs_parse(options, ap, &va);
979 /* External clients need to know where the tmpdir used for
980 communication with the server lives
982 if (jack_get_tmpdir ()) {
983 *status |= JackFailure;
984 return NULL;
987 /* External clients need this initialized. It is already set
988 * up in the server's address space for internal clients.
990 jack_init_time ();
992 if (jack_request_client (ClientExternal, client_name, options, status,
993 &va, &res, &req_fd)) {
994 return NULL;
997 /* Allocate the jack_client_t structure in local memory.
998 * Shared memory is not accessible yet. */
999 client = jack_client_alloc ();
1000 strcpy (client->name, res.name);
1001 strcpy (client->fifo_prefix, res.fifo_prefix);
1002 client->request_fd = req_fd;
1003 client->pollfd[EVENT_POLL_INDEX].events =
1004 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1005 #ifndef JACK_USE_MACH_THREADS
1006 client->pollfd[WAIT_POLL_INDEX].events =
1007 POLLIN|POLLERR|POLLHUP|POLLNVAL;
1008 #endif
1010 /* Don't access shared memory until server connected. */
1011 if (jack_initialize_shm (va.server_name)) {
1012 jack_error ("Unable to initialize shared memory.");
1013 *status |= (JackFailure|JackShmFailure);
1014 goto fail;
1017 /* attach the engine control/info block */
1018 client->engine_shm.index = res.engine_shm_index;
1019 if (jack_attach_shm (&client->engine_shm)) {
1020 jack_error ("cannot attached engine control shared memory"
1021 " segment");
1022 goto fail;
1025 client->engine = (jack_control_t *) jack_shm_addr (&client->engine_shm);
1027 /* initialize clock source as early as possible */
1028 jack_set_clock_source (client->engine->clock_source);
1030 /* now attach the client control block */
1031 client->control_shm.index = res.client_shm_index;
1032 if (jack_attach_shm (&client->control_shm)) {
1033 jack_error ("cannot attached client control shared memory"
1034 " segment");
1035 goto fail;
1038 client->control = (jack_client_control_t *)
1039 jack_shm_addr (&client->control_shm);
1041 /* Nobody else needs to access this shared memory any more, so
1042 * destroy it. Because we have it attached, it won't vanish
1043 * till we exit (and release it).
1045 jack_destroy_shm (&client->control_shm);
1047 client->n_port_types = client->engine->n_port_types;
1048 client->port_segment = (jack_shm_info_t *)
1049 malloc (sizeof (jack_shm_info_t) * client->n_port_types);
1051 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
1052 client->port_segment[ptid].index =
1053 client->engine->port_types[ptid].shm_registry_index;
1054 client->port_segment[ptid].attached_at = MAP_FAILED;
1055 jack_attach_port_segment (client, ptid);
1058 /* set up the client so that it does the right thing for an
1059 * external client
1061 client->deliver_request = oop_client_deliver_request;
1062 client->deliver_arg = client;
1064 if ((ev_fd = server_event_connect (client, va.server_name)) < 0) {
1065 goto fail;
1068 client->event_fd = ev_fd;
1070 #ifdef JACK_USE_MACH_THREADS
1071 /* specific resources for server/client real-time thread
1072 * communication */
1073 client->clienttask = mach_task_self();
1075 if (task_get_bootstrap_port(client->clienttask, &client->bp)){
1076 jack_error ("Can't find bootstrap port");
1077 goto fail;
1080 if (allocate_mach_clientport(client, res.portnum) < 0) {
1081 jack_error("Can't allocate mach port");
1082 goto fail;
1084 #endif /* JACK_USE_MACH_THREADS */
1085 return client;
1087 fail:
1088 if (client->engine) {
1089 jack_release_shm (&client->engine_shm);
1090 client->engine = 0;
1092 if (client->control) {
1093 jack_release_shm (&client->control_shm);
1094 client->control = 0;
1096 if (req_fd >= 0) {
1097 close (req_fd);
1099 if (ev_fd >= 0) {
1100 close (ev_fd);
1102 free (client);
1104 return NULL;
1107 jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
1109 va_list ap;
1110 va_start(ap, status);
1111 jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
1112 va_end(ap);
1113 return res;
1116 jack_client_t *
1117 jack_client_new (const char *client_name)
1119 jack_options_t options = JackUseExactName;
1120 if (getenv("JACK_START_SERVER") == NULL)
1121 options |= JackNoStartServer;
1122 return jack_client_open (client_name, options, NULL);
1125 char *
1126 jack_get_client_name (jack_client_t *client)
1128 return client->name;
1132 jack_internal_client_new (const char *client_name,
1133 const char *so_name, const char *so_data)
1135 jack_client_connect_result_t res;
1136 int req_fd;
1137 jack_varargs_t va;
1138 jack_status_t status;
1139 jack_options_t options = JackUseExactName;
1141 if (getenv("JACK_START_SERVER") == NULL)
1142 options |= JackNoStartServer;
1144 jack_varargs_init (&va);
1145 va.load_name = (char *) so_name;
1146 va.load_init = (char *) so_data;
1148 return jack_request_client (ClientInternal, client_name,
1149 options, &status, &va, &res, &req_fd);
1152 char *
1153 jack_default_server_name (void)
1155 char *server_name;
1156 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
1157 server_name = "default";
1158 return server_name;
1161 /* returns the name of the per-user subdirectory of jack_tmpdir */
1162 char *
1163 jack_user_dir (void)
1165 static char user_dir[PATH_MAX+1] = "";
1167 /* format the path name on the first call */
1168 if (user_dir[0] == '\0') {
1169 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
1170 snprintf (user_dir, sizeof (user_dir), "%s/jack",
1171 jack_tmpdir);
1172 } else {
1173 snprintf (user_dir, sizeof (user_dir), "%s/jack-%d",
1174 jack_tmpdir, getuid ());
1178 return user_dir;
1181 /* returns the name of the per-server subdirectory of jack_user_dir() */
1182 char *
1183 jack_server_dir (const char *server_name, char *server_dir)
1185 /* format the path name into the suppled server_dir char array,
1186 * assuming that server_dir is at least as large as PATH_MAX+1 */
1188 snprintf (server_dir, PATH_MAX+1, "%s/%s",
1189 jack_user_dir (), server_name);
1191 return server_dir;
1194 void
1195 jack_internal_client_close (const char *client_name)
1197 jack_client_connect_request_t req;
1198 int fd;
1199 char *server_name = jack_default_server_name ();
1201 req.load = FALSE;
1202 snprintf (req.name, sizeof (req.name), "%s", client_name);
1204 if ((fd = server_connect (server_name)) < 0) {
1205 return;
1208 if (write (fd, &req, sizeof (req)) != sizeof(req)) {
1209 jack_error ("cannot deliver ClientUnload request to JACK "
1210 "server.");
1213 /* no response to this request */
1215 close (fd);
1216 return;
1220 jack_recompute_total_latencies (jack_client_t* client)
1222 jack_request_t request;
1224 request.type = RecomputeTotalLatencies;
1225 return jack_client_deliver_request (client, &request);
1229 jack_recompute_total_latency (jack_client_t* client, jack_port_t* port)
1231 jack_request_t request;
1233 request.type = RecomputeTotalLatency;
1234 request.x.port_info.port_id = port->shared->id;
1235 return jack_client_deliver_request (client, &request);
1239 jack_set_freewheel (jack_client_t* client, int onoff)
1241 jack_request_t request;
1243 request.type = onoff ? FreeWheel : StopFreeWheel;
1244 return jack_client_deliver_request (client, &request);
1247 void
1248 jack_start_freewheel (jack_client_t* client)
1250 jack_client_control_t *control = client->control;
1252 if (client->engine->real_time) {
1253 #if JACK_USE_MACH_THREADS
1254 jack_drop_real_time_scheduling (client->process_thread);
1255 #else
1256 jack_drop_real_time_scheduling (client->thread);
1257 #endif
1260 if (control->freewheel_cb_cbset) {
1261 client->freewheel_cb (1, client->freewheel_arg);
1265 void
1266 jack_stop_freewheel (jack_client_t* client)
1268 jack_client_control_t *control = client->control;
1270 if (client->engine->real_time) {
1271 #if JACK_USE_MACH_THREADS
1272 jack_acquire_real_time_scheduling (client->process_thread,
1273 client->engine->client_priority);
1274 #else
1275 jack_acquire_real_time_scheduling (client->thread,
1276 client->engine->client_priority);
1277 #endif
1280 if (control->freewheel_cb_cbset) {
1281 client->freewheel_cb (0, client->freewheel_arg);
1285 static void
1286 jack_client_thread_suicide (jack_client_t* client)
1288 if (client->on_shutdown) {
1289 jack_error ("zombified - calling shutdown handler");
1290 client->on_shutdown (client->on_shutdown_arg);
1291 } else {
1292 jack_error ("jack_client_thread zombified - exiting from JACK");
1293 jack_client_close_aux (client);
1294 /* Need a fix : possibly make client crash if
1295 * zombified without shutdown handler
1299 pthread_exit (0);
1300 /*NOTREACHED*/
1303 static int
1304 jack_client_process_events (jack_client_t* client)
1306 jack_event_t event;
1307 char status = 0;
1308 jack_client_control_t *control = client->control;
1309 JSList *node;
1310 jack_port_t* port;
1312 DEBUG ("process events");
1314 if (client->pollfd[EVENT_POLL_INDEX].revents & POLLIN) {
1316 DEBUG ("client receives an event, "
1317 "now reading on event fd");
1319 /* server has sent us an event. process the
1320 * event and reply */
1322 if (read (client->event_fd, &event, sizeof (event))
1323 != sizeof (event)) {
1324 jack_error ("cannot read server event (%s)",
1325 strerror (errno));
1326 return -1;
1329 status = 0;
1331 switch (event.type) {
1332 case PortRegistered:
1333 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
1334 port = node->data;
1335 if (port->shared->id == event.x.port_id) { // Found port, update port type
1336 port->type_info = &client->engine->port_types[port->shared->ptype_id];
1339 if (control->port_register_cbset) {
1340 client->port_register
1341 (event.x.port_id, TRUE,
1342 client->port_register_arg);
1344 break;
1346 case PortUnregistered:
1347 if (control->port_register_cbset) {
1348 client->port_register
1349 (event.x.port_id, FALSE,
1350 client->port_register_arg);
1352 break;
1354 case ClientRegistered:
1355 if (control->client_register_cbset) {
1356 client->client_register
1357 (event.x.name, TRUE,
1358 client->client_register_arg);
1360 break;
1362 case ClientUnregistered:
1363 if (control->client_register_cbset) {
1364 client->client_register
1365 (event.x.name, FALSE,
1366 client->client_register_arg);
1368 break;
1370 case GraphReordered:
1371 status = jack_handle_reorder (client, &event);
1372 break;
1374 case PortConnected:
1375 case PortDisconnected:
1376 status = jack_client_handle_port_connection
1377 (client, &event);
1378 break;
1380 case BufferSizeChange:
1381 jack_client_invalidate_port_buffers (client);
1382 if (control->bufsize_cbset) {
1383 status = client->bufsize
1384 (control->nframes,
1385 client->bufsize_arg);
1387 break;
1389 case SampleRateChange:
1390 if (control->srate_cbset) {
1391 status = client->srate
1392 (control->nframes,
1393 client->srate_arg);
1395 break;
1397 case XRun:
1398 if (control->xrun_cbset) {
1399 status = client->xrun
1400 (client->xrun_arg);
1402 break;
1404 case AttachPortSegment:
1405 jack_attach_port_segment (client, event.y.ptid);
1406 break;
1408 case StartFreewheel:
1409 jack_start_freewheel (client);
1410 break;
1412 case StopFreewheel:
1413 jack_stop_freewheel (client);
1414 break;
1417 DEBUG ("client has dealt with the event, writing "
1418 "response on event fd");
1420 if (write (client->event_fd, &status, sizeof (status))
1421 != sizeof (status)) {
1422 jack_error ("cannot send event response to "
1423 "engine (%s)", strerror (errno));
1424 return -1;
1428 return 0;
1431 static int
1432 jack_client_core_wait (jack_client_t* client)
1434 jack_client_control_t *control = client->control;
1436 DEBUG ("client polling on %s", client->pollmax == 2 ?
1437 "event_fd and graph_wait_fd..." :
1438 "event_fd only");
1440 while (1) {
1441 if (poll (client->pollfd, client->pollmax, 1000) < 0) {
1442 if (errno == EINTR) {
1443 continue;
1445 jack_error ("poll failed in client (%s)",
1446 strerror (errno));
1447 return -1;
1450 pthread_testcancel();
1452 #ifndef JACK_USE_MACH_THREADS
1454 /* get an accurate timestamp on waking from poll for a
1455 * process() cycle.
1458 if (client->graph_wait_fd >= 0
1459 && client->pollfd[WAIT_POLL_INDEX].revents & POLLIN) {
1460 control->awake_at = jack_get_microseconds();
1463 DEBUG ("pfd[EVENT].revents = 0x%x pfd[WAIT].revents = 0x%x",
1464 client->pollfd[EVENT_POLL_INDEX].revents,
1465 client->pollfd[WAIT_POLL_INDEX].revents);
1467 if (client->graph_wait_fd >= 0 &&
1468 (client->pollfd[WAIT_POLL_INDEX].revents & ~POLLIN)) {
1470 /* our upstream "wait" connection
1471 closed, which either means that
1472 an intermediate client exited, or
1473 jackd exited, or jackd zombified
1476 we can discover the zombification
1477 via client->control->dead, but
1478 the other two possibilities are
1479 impossible to identify just from
1480 this situation. so we have to
1481 check what we are connected to,
1482 and act accordingly.
1485 if (client->upstream_is_jackd) {
1486 DEBUG ("WE DIE\n");
1487 return 0;
1488 } else {
1489 DEBUG ("WE PUNT\n");
1490 /* don't poll on the wait fd
1491 * again until we get a
1492 * GraphReordered event.
1495 client->graph_wait_fd = -1;
1496 client->pollmax = 1;
1499 #endif
1501 if (jack_client_process_events (client)) {
1502 DEBUG ("event processing failed\n");
1503 return 0;
1506 if (client->graph_wait_fd >= 0 &&
1507 (client->pollfd[WAIT_POLL_INDEX].revents & POLLIN)) {
1508 DEBUG ("time to run process()\n");
1509 break;
1513 if (control->dead || client->pollfd[EVENT_POLL_INDEX].revents & ~POLLIN) {
1514 DEBUG ("client appears dead or event pollfd has error status\n");
1515 return -1;
1518 return 0;
1521 static int
1522 jack_wake_next_client (jack_client_t* client)
1524 struct pollfd pfds[1];
1525 int pret = 0;
1526 char c = 0;
1528 if (write (client->graph_next_fd, &c, sizeof (c))
1529 != sizeof (c)) {
1530 DEBUG("cannot write byte to fd %d", client->graph_next_fd);
1531 jack_error ("cannot continue execution of the "
1532 "processing graph (%s)",
1533 strerror(errno));
1534 return -1;
1537 DEBUG ("client sent message to next stage by %" PRIu64 "",
1538 jack_get_microseconds());
1540 DEBUG("reading cleanup byte from pipe %d\n", client->graph_wait_fd);
1542 /* "upstream client went away? readability is checked in
1543 * jack_client_core_wait(), but that's almost a whole cycle
1544 * before we get here.
1547 if (client->graph_wait_fd >= 0) {
1548 pfds[0].fd = client->graph_wait_fd;
1549 pfds[0].events = POLLIN;
1551 /* 0 timeout, don't actually wait */
1552 pret = poll(pfds, 1, 0);
1555 if (pret > 0 && (pfds[0].revents & POLLIN)) {
1556 if (read (client->graph_wait_fd, &c, sizeof (c))
1557 != sizeof (c)) {
1558 jack_error ("cannot complete execution of the "
1559 "processing graph (%s)", strerror(errno));
1560 return -1;
1562 } else {
1563 DEBUG("cleanup byte from pipe %d not available?\n",
1564 client->graph_wait_fd);
1567 return 0;
1570 static jack_nframes_t
1571 jack_thread_first_wait (jack_client_t* client)
1573 if (jack_client_core_wait (client)) {
1574 return 0;
1576 return client->control->nframes;
1579 jack_nframes_t
1580 jack_thread_wait (jack_client_t* client, int status)
1582 client->control->last_status = status;
1584 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1586 /* housekeeping/cleanup after data processing */
1588 if (status == 0 && client->control->timebase_cb_cbset) {
1589 jack_call_timebase_master (client);
1592 /* end preemption checking */
1593 CHECK_PREEMPTION (client->engine, FALSE);
1595 client->control->finished_at = jack_get_microseconds();
1597 /* wake the next client in the chain (could be the server),
1598 and check if we were killed during the process
1599 cycle.
1602 if (jack_wake_next_client (client)) {
1603 DEBUG("client cannot wake next, or is dead\n");
1604 return 0;
1607 if (status || client->control->dead || !client->engine->engine_ok) {
1608 return 0;
1611 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1613 if (jack_client_core_wait (client)) {
1614 return 0;
1617 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1619 /* Time to do data processing */
1621 client->control->state = Running;
1623 /* begin preemption checking */
1624 CHECK_PREEMPTION (client->engine, TRUE);
1626 if (client->control->sync_cb_cbset)
1627 jack_call_sync_client (client);
1629 return client->control->nframes;
1632 jack_nframes_t jack_cycle_wait (jack_client_t* client)
1634 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1636 if (jack_client_core_wait (client)) {
1637 return 0;
1640 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1642 /* Time to do data processing */
1644 client->control->state = Running;
1646 /* begin preemption checking */
1647 CHECK_PREEMPTION (client->engine, TRUE);
1649 if (client->control->sync_cb_cbset)
1650 jack_call_sync_client (client);
1652 return client->control->nframes;
1655 void jack_cycle_signal(jack_client_t* client, int status)
1657 client->control->last_status = status;
1659 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1661 /* housekeeping/cleanup after data processing */
1663 if (status == 0 && client->control->timebase_cb_cbset) {
1664 jack_call_timebase_master (client);
1667 /* end preemption checking */
1668 CHECK_PREEMPTION (client->engine, FALSE);
1670 client->control->finished_at = jack_get_microseconds();
1672 /* wake the next client in the chain (could be the server),
1673 and check if we were killed during the process
1674 cycle.
1677 if (jack_wake_next_client (client)) {
1678 DEBUG("client cannot wake next, or is dead\n");
1679 jack_client_thread_suicide (client);
1680 /*NOTREACHED*/
1683 if (status || client->control->dead || !client->engine->engine_ok) {
1684 jack_client_thread_suicide (client);
1685 /*NOTREACHED*/
1689 static void
1690 jack_client_thread_aux (void *arg)
1692 jack_client_t *client = (jack_client_t *) arg;
1693 jack_client_control_t *control = client->control;
1695 pthread_mutex_lock (&client_lock);
1696 client->thread_ok = TRUE;
1697 client->thread_id = pthread_self();
1698 pthread_cond_signal (&client_ready);
1699 pthread_mutex_unlock (&client_lock);
1701 control->pid = getpid();
1702 control->pgrp = getpgrp();
1704 DEBUG ("client thread is now running");
1706 if (control->thread_init_cbset) {
1707 DEBUG ("calling client thread init callback");
1708 client->thread_init (client->thread_init_arg);
1711 /* wait for first wakeup from server */
1713 if (jack_thread_first_wait (client) == control->nframes) {
1715 /* now run till we're done */
1717 if (control->process_cbset) {
1719 /* run process callback, then wait... ad-infinitum */
1721 while (1) {
1722 DEBUG("client calls process()");
1723 int status = (client->process (control->nframes,
1724 client->process_arg) ==
1725 control->nframes);
1726 control->state = Finished;
1727 DEBUG("client leaves process(), re-enters wait");
1728 if (!jack_thread_wait (client, status)) {
1729 break;
1731 DEBUG("client done with wait");
1734 } else {
1735 /* no process handling but still need to process events */
1736 while (jack_thread_wait (client, 0) == control->nframes)
1741 jack_client_thread_suicide (client);
1744 static void *
1745 jack_client_thread (void *arg)
1747 jack_client_t *client = (jack_client_t *) arg;
1748 jack_client_control_t *control = client->control;
1750 if (client->control->thread_cb_cbset) {
1752 pthread_mutex_lock (&client_lock);
1753 client->thread_ok = TRUE;
1754 client->thread_id = pthread_self();
1755 pthread_cond_signal (&client_ready);
1756 pthread_mutex_unlock (&client_lock);
1758 control->pid = getpid();
1759 control->pgrp = getpgrp();
1761 client->thread_cb(client->thread_cb_arg);
1762 jack_client_thread_suicide(client);
1763 } else {
1764 jack_client_thread_aux(arg);
1767 /*NOTREACHED*/
1768 return (void *) 0;
1771 #ifdef JACK_USE_MACH_THREADS
1772 /* real-time thread : separated from the normal client thread, it will
1773 * communicate with the server using fast mach RPC mechanism */
1775 static void *
1776 jack_client_process_thread (void *arg)
1778 jack_client_t *client = (jack_client_t *) arg;
1779 jack_client_control_t *control = client->control;
1780 int err = 0;
1782 if (client->control->thread_init_cbset) {
1783 /* this means that the init callback will be called twice -taybin*/
1784 DEBUG ("calling client thread init callback");
1785 client->thread_init (client->thread_init_arg);
1788 client->control->pid = getpid();
1789 DEBUG ("client process thread is now running");
1791 client->rt_thread_ok = TRUE;
1793 while (err == 0) {
1795 if (jack_client_suspend(client) < 0) {
1796 jack_error ("jack_client_process_thread :resume error");
1797 goto zombie;
1800 control->awake_at = jack_get_microseconds();
1802 DEBUG ("client resumed");
1804 control->state = Running;
1806 if (control->sync_cb_cbset)
1807 jack_call_sync_client (client);
1809 if (control->process_cbset) {
1810 if (client->process (control->nframes,
1811 client->process_arg) == 0) {
1812 control->state = Finished;
1814 } else {
1815 control->state = Finished;
1818 if (control->timebase_cb_cbset)
1819 jack_call_timebase_master (client);
1821 control->finished_at = jack_get_microseconds();
1823 DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
1824 control->finished_at,
1825 ((float)(control->finished_at - control->awake_at)));
1827 /* check if we were killed during the process cycle
1828 * (or whatever) */
1830 if (client->control->dead) {
1831 jack_error ("jack_client_process_thread: "
1832 "client->control->dead");
1833 goto zombie;
1836 DEBUG("process cycle fully complete\n");
1840 return (void *) ((intptr_t)err);
1842 zombie:
1844 jack_error ("jack_client_process_thread : zombified");
1846 client->rt_thread_ok = FALSE;
1848 if (client->on_shutdown) {
1849 jack_error ("zombified - calling shutdown handler");
1850 client->on_shutdown (client->on_shutdown_arg);
1851 } else {
1852 jack_error ("jack_client_process_thread zombified - exiting from JACK");
1853 /* Need a fix : possibly make client crash if
1854 * zombified without shutdown handler */
1855 jack_client_close_aux (client);
1858 pthread_exit (0);
1859 /*NOTREACHED*/
1860 return 0;
1862 #endif /* JACK_USE_MACH_THREADS */
1864 static int
1865 jack_start_thread (jack_client_t *client)
1867 if (client->engine->real_time) {
1869 #ifdef USE_MLOCK
1870 if (client->engine->do_mlock
1871 && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) {
1872 jack_error ("cannot lock down memory for RT thread "
1873 "(%s)", strerror (errno));
1875 #ifdef ENSURE_MLOCK
1876 return -1;
1877 #endif /* ENSURE_MLOCK */
1880 if (client->engine->do_munlock) {
1881 cleanup_mlock ();
1883 #endif /* USE_MLOCK */
1886 #ifdef JACK_USE_MACH_THREADS
1887 /* Stephane Letz : letz@grame.fr
1888 On MacOSX, the normal thread does not need to be real-time.
1890 if (jack_client_create_thread (client,
1891 &client->thread,
1892 client->engine->client_priority,
1893 FALSE,
1894 jack_client_thread, client)) {
1895 return -1;
1897 #else
1898 if (jack_client_create_thread (client,
1899 &client->thread,
1900 client->engine->client_priority,
1901 client->engine->real_time,
1902 jack_client_thread, client)) {
1903 return -1;
1906 #endif
1908 #ifdef JACK_USE_MACH_THREADS
1910 /* a secondary thread that runs the process callback and uses
1911 ultra-fast Mach primitives for inter-thread signalling.
1913 XXX in a properly structured JACK, there would be no
1914 need for this, because we would have client wake up
1915 methods that encapsulated the underlying mechanism
1916 used.
1920 if (jack_client_create_thread(client,
1921 &client->process_thread,
1922 client->engine->client_priority,
1923 client->engine->real_time,
1924 jack_client_process_thread, client)) {
1925 return -1;
1927 #endif /* JACK_USE_MACH_THREADS */
1929 return 0;
1932 int
1933 jack_activate (jack_client_t *client)
1935 jack_request_t req;
1937 /* we need to scribble on our stack to ensure that its memory
1938 * pages are actually mapped (more important for mlockall(2)
1939 * usage in jack_start_thread())
1942 char buf[JACK_THREAD_STACK_TOUCH];
1943 int i;
1945 for (i = 0; i < JACK_THREAD_STACK_TOUCH; i++) {
1946 buf[i] = (char) (i & 0xff);
1949 if (client->control->type == ClientInternal ||
1950 client->control->type == ClientDriver) {
1951 goto startit;
1954 /* get the pid of the client process to pass it to engine */
1956 client->control->pid = getpid ();
1958 #ifdef USE_CAPABILITIES
1960 if (client->engine->has_capabilities != 0 &&
1961 client->control->pid != 0 && client->engine->real_time != 0) {
1963 /* we need to ask the engine for realtime capabilities
1964 before trying to start the realtime thread
1967 req.type = SetClientCapabilities;
1968 req.x.client_id = client->control->id;
1969 req.x.cap_pid = client->control->pid;
1971 jack_client_deliver_request (client, &req);
1973 if (req.status) {
1975 /* what to do? engine is running realtime, it
1976 is using capabilities and has them
1977 (otherwise we would not get an error
1978 return) but for some reason it could not
1979 give the client the required capabilities.
1980 For now, leave the client so that it
1981 still runs, albeit non-realtime.
1984 jack_error ("could not receive realtime capabilities, "
1985 "client will run non-realtime");
1988 #endif /* USE_CAPABILITIES */
1990 if (client->first_active) {
1992 pthread_mutex_init (&client_lock, NULL);
1993 pthread_cond_init (&client_ready, NULL);
1995 pthread_mutex_lock (&client_lock);
1997 if (jack_start_thread (client)) {
1998 pthread_mutex_unlock (&client_lock);
1999 return -1;
2002 pthread_cond_wait (&client_ready, &client_lock);
2003 pthread_mutex_unlock (&client_lock);
2005 if (!client->thread_ok) {
2006 jack_error ("could not start client thread");
2007 return -1;
2010 client->first_active = FALSE;
2013 startit:
2015 req.type = ActivateClient;
2016 req.x.client_id = client->control->id;
2018 return jack_client_deliver_request (client, &req);
2021 static int
2022 jack_deactivate_aux (jack_client_t *client)
2024 jack_request_t req;
2025 int rc = ESRCH; /* already shut down */
2027 if (client && client->control) { /* not shut down? */
2028 rc = 0;
2029 if (client->control->active) { /* still active? */
2030 req.type = DeactivateClient;
2031 req.x.client_id = client->control->id;
2032 rc = jack_client_deliver_request (client, &req);
2035 return rc;
2038 int
2039 jack_deactivate (jack_client_t *client)
2041 return jack_deactivate_aux(client);
2044 static int
2045 jack_client_close_aux (jack_client_t *client)
2047 JSList *node;
2048 void *status;
2049 int rc;
2051 rc = jack_deactivate_aux (client);
2052 if (rc == ESRCH) { /* already shut down? */
2053 return rc;
2056 if (client->control->type == ClientExternal) {
2058 #if JACK_USE_MACH_THREADS
2059 if (client->rt_thread_ok) {
2060 // MacOSX pthread_cancel not implemented in
2061 // Darwin 5.5, 6.4
2062 mach_port_t machThread =
2063 pthread_mach_thread_np (client->process_thread);
2064 thread_terminate (machThread);
2066 #endif
2068 /* stop the thread that communicates with the jack
2069 * server, only if it was actually running
2072 if (client->thread_ok){
2073 pthread_cancel (client->thread);
2074 pthread_join (client->thread, &status);
2077 if (client->control) {
2078 jack_release_shm (&client->control_shm);
2079 client->control = NULL;
2081 if (client->engine) {
2082 jack_release_shm (&client->engine_shm);
2083 client->engine = NULL;
2086 if (client->port_segment) {
2087 jack_port_type_id_t ptid;
2088 for (ptid = 0; ptid < client->n_port_types; ++ptid) {
2089 jack_release_shm (&client->port_segment[ptid]);
2091 free (client->port_segment);
2092 client->port_segment = NULL;
2095 #ifndef JACK_USE_MACH_THREADS
2096 if (client->graph_wait_fd >= 0) {
2097 close (client->graph_wait_fd);
2100 if (client->graph_next_fd >= 0) {
2101 close (client->graph_next_fd);
2103 #endif
2105 close (client->event_fd);
2107 if (shutdown (client->request_fd, SHUT_RDWR)) {
2108 jack_error ("could not shutdown client request socket");
2111 close (client->request_fd);
2115 for (node = client->ports; node; node = jack_slist_next (node)) {
2116 free (node->data);
2118 jack_slist_free (client->ports);
2119 for (node = client->ports_ext; node; node = jack_slist_next (node)) {
2120 free (node->data);
2122 jack_slist_free (client->ports_ext);
2123 jack_client_free (client);
2124 jack_messagebuffer_exit ();
2126 return rc;
2130 jack_client_close (jack_client_t *client)
2132 return jack_client_close_aux(client);
2135 int
2136 jack_is_realtime (jack_client_t *client)
2138 return client->engine->real_time;
2141 jack_nframes_t
2142 jack_get_buffer_size (jack_client_t *client)
2144 return client->engine->buffer_size;
2148 jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
2150 #ifdef DO_BUFFER_RESIZE
2151 jack_request_t req;
2153 req.type = SetBufferSize;
2154 req.x.nframes = nframes;
2156 return jack_client_deliver_request (client, &req);
2157 #else
2158 return ENOSYS;
2160 #endif /* DO_BUFFER_RESIZE */
2163 int
2164 jack_connect (jack_client_t *client, const char *source_port,
2165 const char *destination_port)
2167 jack_request_t req;
2169 req.type = ConnectPorts;
2171 snprintf (req.x.connect.source_port,
2172 sizeof (req.x.connect.source_port), "%s", source_port);
2173 snprintf (req.x.connect.destination_port,
2174 sizeof (req.x.connect.destination_port),
2175 "%s", destination_port);
2177 return jack_client_deliver_request (client, &req);
2181 jack_port_disconnect (jack_client_t *client, jack_port_t *port)
2183 jack_request_t req;
2185 pthread_mutex_lock (&port->connection_lock);
2187 if (port->connections == NULL) {
2188 pthread_mutex_unlock (&port->connection_lock);
2189 return 0;
2192 pthread_mutex_unlock (&port->connection_lock);
2194 req.type = DisconnectPort;
2195 req.x.port_info.port_id = port->shared->id;
2197 return jack_client_deliver_request (client, &req);
2200 int
2201 jack_disconnect (jack_client_t *client, const char *source_port,
2202 const char *destination_port)
2204 jack_request_t req;
2206 req.type = DisconnectPorts;
2208 snprintf (req.x.connect.source_port,
2209 sizeof (req.x.connect.source_port), "%s", source_port);
2210 snprintf (req.x.connect.destination_port,
2211 sizeof (req.x.connect.destination_port),
2212 "%s", destination_port);
2214 return jack_client_deliver_request (client, &req);
2217 void
2218 jack_set_error_function (void (*func) (const char *))
2220 jack_error_callback = func;
2223 void
2224 jack_set_info_function (void (*func) (const char *))
2226 jack_info_callback = func;
2229 int
2230 jack_set_graph_order_callback (jack_client_t *client,
2231 JackGraphOrderCallback callback, void *arg)
2233 if (client->control->active) {
2234 jack_error ("You cannot set callbacks on an active client.");
2235 return -1;
2237 client->graph_order = callback;
2238 client->graph_order_arg = arg;
2239 client->control->graph_order_cbset = (callback != NULL);
2240 return 0;
2243 int jack_set_xrun_callback (jack_client_t *client,
2244 JackXRunCallback callback, void *arg)
2246 if (client->control->active) {
2247 jack_error ("You cannot set callbacks on an active client.");
2248 return -1;
2251 client->xrun = callback;
2252 client->xrun_arg = arg;
2253 client->control->xrun_cbset = (callback != NULL);
2254 return 0;
2258 jack_set_process_callback (jack_client_t *client,
2259 JackProcessCallback callback, void *arg)
2262 if (client->control->active) {
2263 jack_error ("You cannot set callbacks on an active client.");
2264 return -1;
2267 if (client->control->thread_cb_cbset) {
2268 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
2269 return -1;
2272 client->process_arg = arg;
2273 client->process = callback;
2274 client->control->process_cbset = (callback != NULL);
2275 return 0;
2279 jack_set_thread_init_callback (jack_client_t *client,
2280 JackThreadInitCallback callback, void *arg)
2283 if (client->control->active) {
2284 jack_error ("You cannot set callbacks on an active client.");
2285 return -1;
2287 client->thread_init_arg = arg;
2288 client->thread_init = callback;
2289 client->control->thread_init_cbset = (callback != NULL);
2290 return 0;
2294 jack_set_freewheel_callback (jack_client_t *client,
2295 JackFreewheelCallback callback, void *arg)
2297 if (client->control->active) {
2298 jack_error ("You cannot set callbacks on an active client.");
2299 return -1;
2301 client->freewheel_arg = arg;
2302 client->freewheel_cb = callback;
2303 client->control->freewheel_cb_cbset = (callback != NULL);
2304 return 0;
2308 jack_set_buffer_size_callback (jack_client_t *client,
2309 JackBufferSizeCallback callback, void *arg)
2311 client->bufsize_arg = arg;
2312 client->bufsize = callback;
2313 client->control->bufsize_cbset = (callback != NULL);
2314 return 0;
2318 jack_set_port_registration_callback(jack_client_t *client,
2319 JackPortRegistrationCallback callback,
2320 void *arg)
2322 if (client->control->active) {
2323 jack_error ("You cannot set callbacks on an active client.");
2324 return -1;
2326 client->port_register_arg = arg;
2327 client->port_register = callback;
2328 client->control->port_register_cbset = (callback != NULL);
2329 return 0;
2333 jack_set_port_connect_callback(jack_client_t *client,
2334 JackPortConnectCallback callback,
2335 void *arg)
2337 if (client->control->active) {
2338 jack_error ("You cannot set callbacks on an active client.");
2339 return -1;
2341 client->port_connect_arg = arg;
2342 client->port_connect = callback;
2343 client->control->port_connect_cbset = (callback != NULL);
2344 return 0;
2348 jack_set_client_registration_callback(jack_client_t *client,
2349 JackClientRegistrationCallback callback,
2350 void *arg)
2352 if (client->control->active) {
2353 jack_error ("You cannot set callbacks on an active client.");
2354 return -1;
2356 client->client_register_arg = arg;
2357 client->client_register = callback;
2358 client->control->client_register_cbset = (callback != NULL);
2359 return 0;
2363 jack_set_process_thread(jack_client_t* client, JackThreadCallback callback, void *arg)
2365 if (client->control->active) {
2366 jack_error ("You cannot set callbacks on an active client.");
2367 return -1;
2370 if (client->control->process_cbset) {
2371 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
2372 return -1;
2375 client->thread_cb_arg = arg;
2376 client->thread_cb = callback;
2377 client->control->thread_cb_cbset = (callback != NULL);
2378 return 0;
2382 jack_get_process_done_fd (jack_client_t *client)
2384 return client->graph_next_fd;
2387 void
2388 jack_on_shutdown (jack_client_t *client, void (*function)(void *arg), void *arg)
2390 client->on_shutdown = function;
2391 client->on_shutdown_arg = arg;
2394 const char **
2395 jack_get_ports (jack_client_t *client,
2396 const char *port_name_pattern,
2397 const char *type_name_pattern,
2398 unsigned long flags)
2400 jack_control_t *engine;
2401 const char **matching_ports;
2402 unsigned long match_cnt;
2403 jack_port_shared_t *psp;
2404 unsigned long i;
2405 regex_t port_regex;
2406 regex_t type_regex;
2407 int matching;
2409 engine = client->engine;
2411 if (port_name_pattern && port_name_pattern[0]) {
2412 regcomp (&port_regex, port_name_pattern,
2413 REG_EXTENDED|REG_NOSUB);
2415 if (type_name_pattern && type_name_pattern[0]) {
2416 regcomp (&type_regex, type_name_pattern,
2417 REG_EXTENDED|REG_NOSUB);
2420 psp = engine->ports;
2421 match_cnt = 0;
2423 matching_ports = (const char **)
2424 malloc (sizeof (char *) * engine->port_max);
2426 for (i = 0; i < engine->port_max; i++) {
2427 matching = 1;
2429 if (!psp[i].in_use) {
2430 continue;
2433 if (flags) {
2434 if ((psp[i].flags & flags) != flags) {
2435 matching = 0;
2439 if (matching && port_name_pattern && port_name_pattern[0]) {
2440 if (regexec (&port_regex, psp[i].name, 0, NULL, 0)) {
2441 matching = 0;
2445 if (matching && type_name_pattern && type_name_pattern[0]) {
2446 jack_port_type_id_t ptid = psp[i].ptype_id;
2447 if (regexec (&type_regex,
2448 engine->port_types[ptid].type_name,
2449 0, NULL, 0)) {
2450 matching = 0;
2454 if (matching) {
2455 matching_ports[match_cnt++] = psp[i].name;
2458 if (port_name_pattern && port_name_pattern[0]) {
2459 regfree (&port_regex);
2461 if (type_name_pattern && type_name_pattern[0]) {
2462 regfree (&type_regex);
2465 matching_ports[match_cnt] = 0;
2467 if (match_cnt == 0) {
2468 free (matching_ports);
2469 matching_ports = 0;
2472 return matching_ports;
2475 float
2476 jack_cpu_load (jack_client_t *client)
2478 return client->engine->cpu_load;
2481 float
2482 jack_get_xrun_delayed_usecs (jack_client_t *client)
2484 return client->engine->xrun_delayed_usecs;
2487 float
2488 jack_get_max_delayed_usecs (jack_client_t *client)
2490 return client->engine->max_delayed_usecs;
2493 void
2494 jack_reset_max_delayed_usecs (jack_client_t *client)
2496 client->engine->max_delayed_usecs = 0.0f;
2499 pthread_t
2500 jack_client_thread_id (jack_client_t *client)
2502 return client->thread_id;
2506 jack_client_name_size(void)
2508 return JACK_CLIENT_NAME_SIZE;
2512 jack_port_name_size(void)
2514 return JACK_PORT_NAME_SIZE;
2518 jack_port_type_size(void)
2520 return JACK_PORT_TYPE_SIZE;