more consistent naming of MIDI ports (vs. audio); drop use of ALSA seq client ID...
[jack.git] / jackd / engine.c
blob97ed8fec2f78656109333dc226768c8d4270e798
1 /* -*- mode: c; c-file-style: "bsd"; -*- */
2 /*
3 Copyright (C) 2001-2003 Paul Davis
4 Copyright (C) 2004 Jack O'Quin
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 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 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <config.h>
24 #include <math.h>
25 #include <unistd.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <sys/stat.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <stdarg.h>
33 #ifdef HAVE_STDINT_H
34 #include <stdint.h>
35 #endif
36 #include <dirent.h>
37 #include <signal.h>
38 #include <sys/types.h>
39 #include <string.h>
40 #include <limits.h>
42 #include <jack/internal.h>
43 #include <jack/engine.h>
44 #include <jack/messagebuffer.h>
45 #include <jack/driver.h>
46 #include <jack/shm.h>
47 #include <jack/thread.h>
48 #include <sysdeps/poll.h>
49 #include <sysdeps/ipc.h>
51 #ifdef USE_MLOCK
52 #include <sys/mman.h>
53 #endif /* USE_MLOCK */
55 #ifdef USE_CAPABILITIES
56 /* capgetp and capsetp are linux only extensions, not posix */
57 #undef _POSIX_SOURCE
58 #include <sys/capability.h>
59 #endif
61 #include "clientengine.h"
62 #include "transengine.h"
64 #include "libjack/local.h"
66 typedef struct {
68 jack_port_internal_t *source;
69 jack_port_internal_t *destination;
70 signed int dir; /* -1 = feedback, 0 = self, 1 = forward */
71 jack_client_internal_t *srcclient;
72 jack_client_internal_t *dstclient;
73 } jack_connection_internal_t;
75 typedef struct _jack_driver_info {
76 jack_driver_t *(*initialize)(jack_client_t*, const JSList *);
77 void (*finish);
78 char (*client_name);
79 dlhandle handle;
80 } jack_driver_info_t;
82 jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK;
84 static int jack_port_assign_buffer (jack_engine_t *,
85 jack_port_internal_t *);
86 static jack_port_internal_t *jack_get_port_by_name (jack_engine_t *,
87 const char *name);
88 static int jack_rechain_graph (jack_engine_t *engine);
89 static void jack_clear_fifos (jack_engine_t *engine);
90 static int jack_port_do_connect (jack_engine_t *engine,
91 const char *source_port,
92 const char *destination_port);
93 static int jack_port_do_disconnect (jack_engine_t *engine,
94 const char *source_port,
95 const char *destination_port);
96 static int jack_port_do_disconnect_all (jack_engine_t *engine,
97 jack_port_id_t);
98 static int jack_port_do_unregister (jack_engine_t *engine, jack_request_t *);
99 static int jack_port_do_register (jack_engine_t *engine, jack_request_t *, int);
100 static int jack_do_get_port_connections (jack_engine_t *engine,
101 jack_request_t *req, int reply_fd);
102 static int jack_port_disconnect_internal (jack_engine_t *engine,
103 jack_port_internal_t *src,
104 jack_port_internal_t *dst);
105 static int jack_send_connection_notification (jack_engine_t *,
106 jack_client_id_t,
107 jack_port_id_t,
108 jack_port_id_t, int);
109 static int jack_deliver_event (jack_engine_t *, jack_client_internal_t *,
110 jack_event_t *);
111 static void jack_deliver_event_to_all (jack_engine_t *engine,
112 jack_event_t *event);
113 static void jack_notify_all_port_interested_clients (jack_engine_t *engine,
114 jack_client_id_t exclude_src_id,
115 jack_client_id_t exclude_dst_id,
116 jack_port_id_t a,
117 jack_port_id_t b,
118 int connect);
119 static void jack_engine_post_process (jack_engine_t *);
120 static int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver);
121 static int jack_run_cycle (jack_engine_t *engine, jack_nframes_t nframes,
122 float delayed_usecs);
123 static void jack_engine_delay (jack_engine_t *engine,
124 float delayed_usecs);
125 static void jack_engine_driver_exit (jack_engine_t* engine);
126 static int jack_start_freewheeling (jack_engine_t* engine);
127 static int jack_stop_freewheeling (jack_engine_t* engine);
128 static int jack_client_feeds_transitive (jack_client_internal_t *source,
129 jack_client_internal_t *dest);
130 static int jack_client_sort (jack_client_internal_t *a,
131 jack_client_internal_t *b);
132 static void jack_check_acyclic (jack_engine_t* engine);
133 static void jack_compute_all_port_total_latencies (jack_engine_t *engine);
134 static void jack_compute_port_total_latency (jack_engine_t *engine, jack_port_shared_t*);
137 static inline int
138 jack_rolling_interval (jack_time_t period_usecs)
140 return floor ((JACK_ENGINE_ROLLING_INTERVAL * 1000.0f) / period_usecs);
143 void
144 jack_engine_reset_rolling_usecs (jack_engine_t *engine)
146 memset (engine->rolling_client_usecs, 0,
147 sizeof (engine->rolling_client_usecs));
148 engine->rolling_client_usecs_index = 0;
149 engine->rolling_client_usecs_cnt = 0;
151 if (engine->driver) {
152 engine->rolling_interval =
153 jack_rolling_interval (engine->driver->period_usecs);
154 } else {
155 engine->rolling_interval = JACK_ENGINE_ROLLING_INTERVAL;
158 engine->spare_usecs = 0;
161 static inline jack_port_type_info_t *
162 jack_port_type_info (jack_engine_t *engine, jack_port_internal_t *port)
164 /* Returns a pointer to the port type information in the
165 engine's shared control structure.
167 return &engine->control->port_types[port->shared->ptype_id];
170 static inline jack_port_buffer_list_t *
171 jack_port_buffer_list (jack_engine_t *engine, jack_port_internal_t *port)
173 /* Points to the engine's private port buffer list struct. */
174 return &engine->port_buffers[port->shared->ptype_id];
177 static int
178 make_directory (const char *path)
180 struct stat statbuf;
182 if (stat (path, &statbuf)) {
184 if (errno == ENOENT) {
185 int mode;
187 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
188 mode = 0777;
189 } else {
190 mode = 0700;
193 if (mkdir (path, mode) < 0){
194 jack_error ("cannot create %s directory (%s)\n",
195 path, strerror (errno));
196 return -1;
198 } else {
199 jack_error ("cannot stat() %s\n", path);
200 return -1;
203 } else {
205 if (!S_ISDIR (statbuf.st_mode)) {
206 jack_error ("%s already exists, but is not"
207 " a directory!\n", path);
208 return -1;
212 return 0;
215 static int
216 make_socket_subdirectories (const char *server_name)
218 struct stat statbuf;
219 char server_dir[PATH_MAX+1] = "";
221 /* check tmpdir directory */
222 if (stat (jack_tmpdir, &statbuf)) {
223 jack_error ("cannot stat() %s (%s)\n",
224 jack_tmpdir, strerror (errno));
225 return -1;
226 } else {
227 if (!S_ISDIR(statbuf.st_mode)) {
228 jack_error ("%s exists, but is not a directory!\n",
229 jack_tmpdir);
230 return -1;
234 /* create user subdirectory */
235 if (make_directory (jack_user_dir ()) < 0) {
236 return -1;
239 /* create server_name subdirectory */
240 if (make_directory (jack_server_dir (server_name, server_dir)) < 0) {
241 return -1;
244 return 0;
247 static int
248 make_sockets (const char *server_name, int fd[2])
250 struct sockaddr_un addr;
251 int i;
252 char server_dir[PATH_MAX+1] = "";
254 if (make_socket_subdirectories (server_name) < 0) {
255 return -1;
258 /* First, the master server socket */
260 if ((fd[0] = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
261 jack_error ("cannot create server socket (%s)",
262 strerror (errno));
263 return -1;
266 addr.sun_family = AF_UNIX;
267 for (i = 0; i < 999; i++) {
268 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1,
269 "%s/jack_%d", jack_server_dir (server_name, server_dir), i);
270 if (access (addr.sun_path, F_OK) != 0) {
271 break;
275 if (i == 999) {
276 jack_error ("all possible server socket names in use!!!");
277 close (fd[0]);
278 return -1;
281 if (bind (fd[0], (struct sockaddr *) &addr, sizeof (addr)) < 0) {
282 jack_error ("cannot bind server to socket (%s)",
283 strerror (errno));
284 close (fd[0]);
285 return -1;
288 if (listen (fd[0], 1) < 0) {
289 jack_error ("cannot enable listen on server socket (%s)",
290 strerror (errno));
291 close (fd[0]);
292 return -1;
295 /* Now the client/server event ack server socket */
297 if ((fd[1] = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
298 jack_error ("cannot create event ACK socket (%s)",
299 strerror (errno));
300 close (fd[0]);
301 return -1;
304 addr.sun_family = AF_UNIX;
305 for (i = 0; i < 999; i++) {
306 snprintf (addr.sun_path, sizeof (addr.sun_path) - 1,
307 "%s/jack_ack_%d", jack_server_dir (server_name, server_dir), i);
308 if (access (addr.sun_path, F_OK) != 0) {
309 break;
313 if (i == 999) {
314 jack_error ("all possible server ACK socket names in use!!!");
315 close (fd[0]);
316 close (fd[1]);
317 return -1;
320 if (bind (fd[1], (struct sockaddr *) &addr, sizeof (addr)) < 0) {
321 jack_error ("cannot bind server to socket (%s)",
322 strerror (errno));
323 close (fd[0]);
324 close (fd[1]);
325 return -1;
328 if (listen (fd[1], 1) < 0) {
329 jack_error ("cannot enable listen on server socket (%s)",
330 strerror (errno));
331 close (fd[0]);
332 close (fd[1]);
333 return -1;
336 return 0;
339 void
340 jack_engine_place_port_buffers (jack_engine_t* engine,
341 jack_port_type_id_t ptid,
342 jack_shmsize_t one_buffer,
343 jack_shmsize_t size,
344 unsigned long nports,
345 jack_nframes_t nframes)
347 jack_shmsize_t offset; /* shared memory offset */
348 jack_port_buffer_info_t *bi;
349 jack_port_buffer_list_t* pti = &engine->port_buffers[ptid];
350 jack_port_functions_t *pfuncs = jack_get_port_functions(ptid);
352 pthread_mutex_lock (&pti->lock);
353 offset = 0;
355 if (pti->info) {
357 /* Buffer info array already allocated for this port
358 * type. This must be a resize operation, so
359 * recompute the buffer offsets, but leave the free
360 * list alone.
362 int i;
364 bi = pti->info;
365 while (offset < size) {
366 bi->offset = offset;
367 offset += one_buffer;
368 ++bi;
371 /* update any existing output port offsets */
372 for (i = 0; i < engine->port_max; i++) {
373 jack_port_shared_t *port = &engine->control->ports[i];
374 if (port->in_use &&
375 (port->flags & JackPortIsOutput) &&
376 port->ptype_id == ptid) {
377 bi = engine->internal_ports[i].buffer_info;
378 if (bi) {
379 port->offset = bi->offset;
384 } else {
385 jack_port_type_info_t* port_type = &engine->control->port_types[ptid];
387 /* Allocate an array of buffer info structures for all
388 * the buffers in the segment. Chain them to the free
389 * list in memory address order, offset zero must come
390 * first.
392 bi = pti->info = (jack_port_buffer_info_t *)
393 malloc (nports * sizeof (jack_port_buffer_info_t));
395 while (offset < size) {
396 bi->offset = offset;
397 pti->freelist = jack_slist_append (pti->freelist, bi);
398 offset += one_buffer;
399 ++bi;
402 /* Allocate the first buffer of the port segment
403 * for an empy buffer area.
404 * NOTE: audio buffer is zeroed in its buffer_init function.
406 bi = (jack_port_buffer_info_t *) pti->freelist->data;
407 pti->freelist = jack_slist_remove_link (pti->freelist,
408 pti->freelist);
409 port_type->zero_buffer_offset = bi->offset;
410 if (ptid == JACK_AUDIO_PORT_TYPE)
411 engine->silent_buffer = bi;
413 /* initialize buffers */
415 int i;
416 jack_shm_info_t *shm_info = &engine->port_segment[ptid];
417 char* shm_segment = (char *) jack_shm_addr(shm_info);
419 bi = pti->info;
420 for (i=0; i<nports; ++i, ++bi)
421 pfuncs->buffer_init(shm_segment + bi->offset, one_buffer, nframes);
424 pthread_mutex_unlock (&pti->lock);
427 // JOQ: this should have a return code...
428 static void
429 jack_resize_port_segment (jack_engine_t *engine,
430 jack_port_type_id_t ptid,
431 unsigned long nports)
433 jack_event_t event;
434 jack_shmsize_t one_buffer; /* size of one buffer */
435 jack_shmsize_t size; /* segment size */
436 jack_port_type_info_t* port_type = &engine->control->port_types[ptid];
437 jack_shm_info_t* shm_info = &engine->port_segment[ptid];
439 if (port_type->buffer_scale_factor < 0) {
440 one_buffer = port_type->buffer_size;
441 } else {
442 one_buffer = sizeof (jack_default_audio_sample_t)
443 * port_type->buffer_scale_factor
444 * engine->control->buffer_size;
447 size = nports * one_buffer;
449 if (shm_info->attached_at == 0) {
451 if (jack_shmalloc (size, shm_info)) {
452 jack_error ("cannot create new port segment of %d"
453 " bytes (%s)",
454 size,
455 strerror (errno));
456 return;
459 if (jack_attach_shm (shm_info)) {
460 jack_error ("cannot attach to new port segment "
461 "(%s)", strerror (errno));
462 return;
465 engine->control->port_types[ptid].shm_registry_index =
466 shm_info->index;
468 } else {
470 /* resize existing buffer segment */
471 if (jack_resize_shm (shm_info, size)) {
472 jack_error ("cannot resize port segment to %d bytes,"
473 " (%s)", size,
474 strerror (errno));
475 return;
479 jack_engine_place_port_buffers (engine, ptid, one_buffer, size, nports, engine->control->buffer_size);
481 #ifdef USE_MLOCK
482 if (engine->control->real_time) {
484 /* Although we've called mlockall(CURRENT|FUTURE), the
485 * Linux VM manager still allows newly allocated pages
486 * to fault on first reference. This mlock() ensures
487 * that any new pages are present before restarting
488 * the process cycle. Since memory locks do not
489 * stack, they can still be unlocked with a single
490 * munlockall().
493 int rc = mlock (jack_shm_addr (shm_info), size);
494 if (rc < 0) {
495 jack_error("JACK: unable to mlock() port buffers: "
496 "%s", strerror(errno));
499 #endif /* USE_MLOCK */
501 /* Tell everybody about this segment. */
502 event.type = AttachPortSegment;
503 event.y.ptid = ptid;
504 jack_deliver_event_to_all (engine, &event);
507 /* The driver invokes this callback both initially and whenever its
508 * buffer size changes.
510 static int
511 jack_driver_buffer_size (jack_engine_t *engine, jack_nframes_t nframes)
513 int i;
514 jack_event_t event;
515 JSList *node;
517 VERBOSE (engine, "new buffer size %" PRIu32, nframes);
519 engine->control->buffer_size = nframes;
520 if (engine->driver)
521 engine->rolling_interval =
522 jack_rolling_interval (engine->driver->period_usecs);
524 for (i = 0; i < engine->control->n_port_types; ++i) {
525 jack_resize_port_segment (engine, i, engine->control->port_max);
528 /* update shared client copy of nframes */
529 jack_lock_graph (engine);
530 for (node = engine->clients; node; node = jack_slist_next (node)) {
531 jack_client_internal_t *client = node->data;
532 client->control->nframes = nframes;
534 jack_unlock_graph (engine);
536 event.type = BufferSizeChange;
537 jack_deliver_event_to_all (engine, &event);
539 return 0;
542 /* handle client SetBufferSize request */
544 jack_set_buffer_size_request (jack_engine_t *engine, jack_nframes_t nframes)
546 /* precondition: caller holds the request_lock */
547 int rc;
548 jack_driver_t* driver = engine->driver;
550 if (driver == NULL)
551 return ENXIO; /* no such device */
553 if (!jack_power_of_two(nframes)) {
554 jack_error("buffer size %" PRIu32 " not a power of 2",
555 nframes);
556 return EINVAL;
559 rc = driver->bufsize(driver, nframes);
560 if (rc != 0)
561 jack_error("driver does not support %" PRIu32
562 "-frame buffers", nframes);
564 return rc;
568 static JSList *
569 jack_process_internal(jack_engine_t *engine, JSList *node,
570 jack_nframes_t nframes)
572 jack_client_internal_t *client;
573 jack_client_control_t *ctl;
575 client = (jack_client_internal_t *) node->data;
576 ctl = client->control;
578 /* internal client */
580 DEBUG ("invoking an internal client's callbacks");
581 ctl->state = Running;
582 engine->current_client = client;
584 /* XXX how to time out an internal client? */
586 if (ctl->sync_cb_cbset)
587 jack_call_sync_client (client->private_client);
589 if (ctl->process_cbset)
590 if (client->private_client->process (nframes, client->private_client->process_arg)) {
591 jack_error ("internal client %s failed", ctl->name);
592 engine->process_errors++;
595 if (ctl->timebase_cb_cbset)
596 jack_call_timebase_master (client->private_client);
598 ctl->state = Finished;
600 if (engine->process_errors)
601 return NULL; /* will stop the loop */
602 else
603 return jack_slist_next (node);
606 #ifdef __linux
608 /* Linux kernels somewhere between 2.6.18 and 2.6.24 had a bug
609 in poll(2) that led poll to return early. To fix it, we need
610 to know that that jack_get_microseconds() is monotonic.
613 #ifdef HAVE_CLOCK_GETTIME
614 static const int system_clock_monotonic = 1;
615 #else
616 static const int system_clock_monotonic = 0;
617 #endif
619 static int
620 linux_poll_bug_encountered (jack_engine_t* engine, jack_time_t then, jack_time_t *required)
622 if (engine->control->clock_source != JACK_TIMER_SYSTEM_CLOCK || system_clock_monotonic) {
623 jack_time_t now = jack_get_microseconds ();
625 if ((now - then) < *required) {
628 So, adjust poll timeout to account for time already spent waiting.
631 VERBOSE (engine, "FALSE WAKEUP (%lldusecs vs. %lld usec)", (now - then), *required);
632 *required -= (now - then);
634 /* allow 0.25msec slop */
635 return 1;
638 return 0;
640 #endif
642 #ifdef JACK_USE_MACH_THREADS
643 static JSList *
644 jack_process_external(jack_engine_t *engine, JSList *node)
646 jack_client_internal_t * client = (jack_client_internal_t *) node->data;
647 jack_client_control_t *ctl;
649 client = (jack_client_internal_t *) node->data;
650 ctl = client->control;
652 engine->current_client = client;
654 // a race exists if we do this after the write(2)
655 ctl->state = Triggered;
656 ctl->signalled_at = jack_get_microseconds();
658 if (jack_client_resume(client) < 0) {
659 jack_error("Client will be removed\n");
660 ctl->state = Finished;
663 return jack_slist_next (node);
665 #else /* !JACK_USE_MACH_THREADS */
666 static JSList *
667 jack_process_external(jack_engine_t *engine, JSList *node)
669 int status = 0;
670 char c = 0;
671 struct pollfd pfd[1];
672 int poll_timeout;
673 jack_time_t poll_timeout_usecs;
674 jack_client_internal_t *client;
675 jack_client_control_t *ctl;
676 jack_time_t now, then;
677 int pollret;
679 client = (jack_client_internal_t *) node->data;
681 ctl = client->control;
683 /* external subgraph */
685 /* a race exists if we do this after the write(2) */
686 ctl->state = Triggered;
688 ctl->signalled_at = jack_get_microseconds();
690 engine->current_client = client;
692 DEBUG ("calling process() on an external subgraph, fd==%d",
693 client->subgraph_start_fd);
695 if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) {
696 jack_error ("cannot initiate graph processing (%s)",
697 strerror (errno));
698 engine->process_errors++;
699 jack_lock_problems (engine);
700 engine->problems++;
701 jack_unlock_problems (engine);
702 return NULL; /* will stop the loop */
705 then = jack_get_microseconds ();
707 if (engine->freewheeling) {
708 poll_timeout_usecs = 10000000; /* 10 seconds */
709 } else {
710 poll_timeout_usecs = (engine->client_timeout_msecs > 0 ?
711 engine->client_timeout_msecs * 1000 :
712 engine->driver->period_usecs);
715 again:
716 poll_timeout = 1 + poll_timeout_usecs / 1000;
717 pfd[0].fd = client->subgraph_wait_fd;
718 pfd[0].events = POLLERR|POLLIN|POLLHUP|POLLNVAL;
720 DEBUG ("waiting on fd==%d for process() subgraph to finish (timeout = %d, period_usecs = %d)",
721 client->subgraph_wait_fd, poll_timeout, engine->driver->period_usecs);
723 if ((pollret = poll (pfd, 1, poll_timeout)) < 0) {
724 jack_error ("poll on subgraph processing failed (%s)",
725 strerror (errno));
726 status = -1;
729 DEBUG ("\n\n\n\n\n back from subgraph poll, revents = 0x%x\n\n\n", pfd[0].revents);
731 if (pfd[0].revents & ~POLLIN) {
732 jack_error ("subgraph starting at %s lost client",
733 client->control->name);
734 status = -2;
737 if (pfd[0].revents & POLLIN) {
739 status = 0;
741 } else if (status == 0) {
743 /* no events, no errors, we woke up because poll()
744 decided that time was up ...
747 #ifdef __linux
748 if (linux_poll_bug_encountered (engine, then, &poll_timeout_usecs)) {
749 goto again;
752 if (poll_timeout_usecs < 200) {
753 VERBOSE (engine, "FALSE WAKEUP skipped, remaining = %lld usec", poll_timeout_usecs);
754 } else {
755 #endif
757 jack_error ("subgraph starting at %s timed out "
758 "(subgraph_wait_fd=%d, status = %d, state = %s, pollret = %d revents = 0x%x)",
759 client->control->name,
760 client->subgraph_wait_fd, status,
761 jack_client_state_name (client),
762 pollret, pfd[0].revents);
763 status = 1;
764 #ifdef __linux
766 #endif
769 now = jack_get_microseconds ();
771 if (status != 0) {
772 VERBOSE (engine, "at %" PRIu64
773 " waiting on %d for %" PRIu64
774 " usecs, status = %d sig = %" PRIu64
775 " awa = %" PRIu64 " fin = %" PRIu64
776 " dur=%" PRIu64,
777 now,
778 client->subgraph_wait_fd,
779 now - then,
780 status,
781 ctl->signalled_at,
782 ctl->awake_at,
783 ctl->finished_at,
784 ctl->finished_at? (ctl->finished_at -
785 ctl->signalled_at): 0);
787 jack_check_clients (engine, 1);
789 engine->process_errors++;
790 return NULL; /* will stop the loop */
792 } else {
794 DEBUG ("reading byte from subgraph_wait_fd==%d",
795 client->subgraph_wait_fd);
797 if (read (client->subgraph_wait_fd, &c, sizeof(c))
798 != sizeof (c)) {
799 jack_error ("pp: cannot clean up byte from graph wait "
800 "fd (%s)", strerror (errno));
801 client->error++;
802 return NULL; /* will stop the loop */
806 /* Move to next internal client (or end of client list) */
807 while (node) {
808 if (jack_client_is_internal ((jack_client_internal_t *)
809 node->data)) {
810 break;
812 node = jack_slist_next (node);
815 return node;
818 #endif /* JACK_USE_MACH_THREADS */
820 static int
821 jack_engine_process (jack_engine_t *engine, jack_nframes_t nframes)
823 /* precondition: caller has graph_lock */
824 jack_client_internal_t *client;
825 JSList *node;
827 engine->process_errors = 0;
828 engine->watchdog_check = 1;
830 for (node = engine->clients; node; node = jack_slist_next (node)) {
831 jack_client_control_t *ctl =
832 ((jack_client_internal_t *) node->data)->control;
833 ctl->state = NotTriggered;
834 ctl->nframes = nframes;
835 ctl->timed_out = 0;
836 ctl->awake_at = 0;
837 ctl->finished_at = 0;
840 for (node = engine->clients; engine->process_errors == 0 && node; ) {
842 client = (jack_client_internal_t *) node->data;
844 DEBUG ("considering client %s for processing",
845 client->control->name);
847 if (!client->control->active || client->control->dead) {
848 node = jack_slist_next (node);
849 } else if (jack_client_is_internal (client)) {
850 node = jack_process_internal (engine, node, nframes);
851 } else {
852 node = jack_process_external (engine, node);
856 return engine->process_errors > 0;
859 static void
860 jack_calc_cpu_load(jack_engine_t *engine)
862 jack_time_t cycle_end = jack_get_microseconds ();
864 /* store the execution time for later averaging */
866 engine->rolling_client_usecs[engine->rolling_client_usecs_index++] =
867 cycle_end - engine->control->current_time.usecs;
869 //jack_info ("cycle_end - engine->control->current_time.usecs %ld",
870 // (long) (cycle_end - engine->control->current_time.usecs));
872 if (engine->rolling_client_usecs_index >= JACK_ENGINE_ROLLING_COUNT) {
873 engine->rolling_client_usecs_index = 0;
876 /* every so often, recompute the current maximum use over the
877 last JACK_ENGINE_ROLLING_COUNT client iterations.
880 if (++engine->rolling_client_usecs_cnt
881 % engine->rolling_interval == 0) {
882 float max_usecs = 0.0f;
883 int i;
885 for (i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) {
886 if (engine->rolling_client_usecs[i] > max_usecs) {
887 max_usecs = engine->rolling_client_usecs[i];
891 if (max_usecs > engine->max_usecs) {
892 engine->max_usecs = max_usecs;
895 if (max_usecs < engine->driver->period_usecs) {
896 engine->spare_usecs =
897 engine->driver->period_usecs - max_usecs;
898 } else {
899 engine->spare_usecs = 0;
902 engine->control->cpu_load =
903 (1.0f - (engine->spare_usecs /
904 engine->driver->period_usecs)) * 50.0f
905 + (engine->control->cpu_load * 0.5f);
907 VERBOSE (engine, "load = %.4f max usecs: %.3f, "
908 "spare = %.3f", engine->control->cpu_load,
909 max_usecs, engine->spare_usecs);
914 static void
915 jack_engine_post_process (jack_engine_t *engine)
917 /* precondition: caller holds the graph lock. */
919 jack_transport_cycle_end (engine);
920 jack_calc_cpu_load (engine);
921 jack_check_clients (engine, 0);
924 #ifdef JACK_USE_MACH_THREADS
926 static int
927 jack_start_watchdog (jack_engine_t *engine)
929 /* Stephane Letz : letz@grame.fr Watch dog thread is
930 * not needed on MacOSX since CoreAudio drivers
931 * already contains a similar mechanism.
933 return 0;
936 #else
938 static void *
939 jack_watchdog_thread (void *arg)
941 jack_engine_t *engine = (jack_engine_t *) arg;
942 struct timespec timo;
944 timo.tv_sec = JACKD_WATCHDOG_TIMEOUT / 1000;
945 timo.tv_nsec = (JACKD_WATCHDOG_TIMEOUT - (timo.tv_sec * 1000)) * 1000;
946 engine->watchdog_check = 0;
948 while (1) {
949 nanosleep (&timo, NULL);
950 if (!engine->freewheeling && engine->watchdog_check == 0) {
952 jack_error ("jackd watchdog: timeout - killing jackd");
954 /* Kill the current client (guilt by association). */
955 if (engine->current_client) {
956 kill (engine->current_client->
957 control->pid, SIGKILL);
960 /* kill our process group, try to get a dump */
961 kill (-getpgrp(), SIGABRT);
962 /*NOTREACHED*/
963 exit (1);
965 engine->watchdog_check = 0;
969 static int
970 jack_start_watchdog (jack_engine_t *engine)
972 int watchdog_priority = engine->rtpriority + 10;
973 #ifndef __OpenBSD__
974 int max_priority = sched_get_priority_max (SCHED_FIFO);
975 #else
976 int max_priority = -1;
977 #endif
979 if ((max_priority != -1) &&
980 (max_priority < watchdog_priority))
981 watchdog_priority = max_priority;
983 if (jack_client_create_thread (NULL, &engine->watchdog_thread, watchdog_priority,
984 TRUE, jack_watchdog_thread, engine)) {
985 jack_error ("cannot start watchdog thread");
986 return -1;
989 return 0;
991 #endif /* !JACK_USE_MACH_THREADS */
994 static jack_driver_info_t *
995 jack_load_driver (jack_engine_t *engine, jack_driver_desc_t * driver_desc)
997 const char *errstr;
998 jack_driver_info_t *info;
1000 info = (jack_driver_info_t *) calloc (1, sizeof (*info));
1002 info->handle = dlopen (driver_desc->file, RTLD_NOW|RTLD_GLOBAL);
1004 if (info->handle == NULL) {
1005 if ((errstr = dlerror ()) != 0) {
1006 jack_error ("can't load \"%s\": %s", driver_desc->file,
1007 errstr);
1008 } else {
1009 jack_error ("bizarre error loading driver shared "
1010 "object %s", driver_desc->file);
1012 goto fail;
1015 info->initialize = dlsym (info->handle, "driver_initialize");
1017 if ((errstr = dlerror ()) != 0) {
1018 jack_error ("no initialize function in shared object %s\n",
1019 driver_desc->file);
1020 goto fail;
1023 info->finish = dlsym (info->handle, "driver_finish");
1025 if ((errstr = dlerror ()) != 0) {
1026 jack_error ("no finish function in in shared driver object %s",
1027 driver_desc->file);
1028 goto fail;
1031 info->client_name = (char *) dlsym (info->handle, "driver_client_name");
1033 if ((errstr = dlerror ()) != 0) {
1034 jack_error ("no client name in in shared driver object %s",
1035 driver_desc->file);
1036 goto fail;
1039 return info;
1041 fail:
1042 if (info->handle) {
1043 dlclose (info->handle);
1045 free (info);
1046 return NULL;
1050 void
1051 jack_driver_unload (jack_driver_t *driver)
1053 void* handle = driver->handle;
1054 driver->finish (driver);
1055 dlclose (handle);
1059 jack_engine_load_driver (jack_engine_t *engine,
1060 jack_driver_desc_t * driver_desc,
1061 JSList * driver_params)
1063 jack_client_internal_t *client;
1064 jack_driver_t *driver;
1065 jack_driver_info_t *info;
1067 if ((info = jack_load_driver (engine, driver_desc)) == NULL) {
1068 return -1;
1071 if ((client = jack_create_driver_client (engine, info->client_name)
1072 ) == NULL) {
1073 return -1;
1076 if ((driver = info->initialize (client->private_client,
1077 driver_params)) == NULL) {
1078 free (info);
1079 return -1;
1082 driver->handle = info->handle;
1083 driver->finish = info->finish;
1084 driver->internal_client = client;
1085 free (info);
1087 if (jack_use_driver (engine, driver) < 0) {
1088 jack_client_delete (engine, client);
1089 return -1;
1092 engine->driver_desc = driver_desc;
1093 engine->driver_params = driver_params;
1095 if (engine->control->real_time) {
1096 if (jack_start_watchdog (engine)) {
1097 return -1;
1099 engine->watchdog_check = 1;
1101 return 0;
1104 #ifdef USE_CAPABILITIES
1106 static int check_capabilities (jack_engine_t *engine)
1108 cap_t caps = cap_init();
1109 cap_flag_value_t cap;
1110 pid_t pid;
1111 int have_all_caps = 1;
1113 if (caps == NULL) {
1114 VERBOSE (engine, "check: could not allocate capability"
1115 " working storage");
1116 return 0;
1118 pid = getpid ();
1119 cap_clear (caps);
1120 if (capgetp (pid, caps)) {
1121 VERBOSE (engine, "check: could not get capabilities "
1122 "for process %d", pid);
1123 return 0;
1125 /* check that we are able to give capabilites to other processes */
1126 cap_get_flag(caps, CAP_SETPCAP, CAP_EFFECTIVE, &cap);
1127 if (cap == CAP_CLEAR) {
1128 have_all_caps = 0;
1129 goto done;
1131 /* check that we have the capabilities we want to transfer */
1132 cap_get_flag(caps, CAP_SYS_NICE, CAP_EFFECTIVE, &cap);
1133 if (cap == CAP_CLEAR) {
1134 have_all_caps = 0;
1135 goto done;
1137 cap_get_flag(caps, CAP_SYS_RESOURCE, CAP_EFFECTIVE, &cap);
1138 if (cap == CAP_CLEAR) {
1139 have_all_caps = 0;
1140 goto done;
1142 cap_get_flag(caps, CAP_IPC_LOCK, CAP_EFFECTIVE, &cap);
1143 if (cap == CAP_CLEAR) {
1144 have_all_caps = 0;
1145 goto done;
1147 done:
1148 cap_free (caps);
1149 return have_all_caps;
1153 static int give_capabilities (jack_engine_t *engine, pid_t pid)
1155 cap_t caps = cap_init();
1156 const unsigned caps_size = 3;
1157 cap_value_t cap_list[] = {CAP_SYS_NICE, CAP_SYS_RESOURCE, CAP_IPC_LOCK};
1159 if (caps == NULL) {
1160 VERBOSE (engine, "give: could not allocate capability"
1161 " working storage");
1162 return -1;
1164 cap_clear(caps);
1165 if (capgetp (pid, caps)) {
1166 VERBOSE (engine, "give: could not get current "
1167 "capabilities for process %d", pid);
1168 cap_clear(caps);
1170 cap_set_flag(caps, CAP_EFFECTIVE, caps_size, cap_list , CAP_SET);
1171 cap_set_flag(caps, CAP_INHERITABLE, caps_size, cap_list , CAP_SET);
1172 cap_set_flag(caps, CAP_PERMITTED, caps_size, cap_list , CAP_SET);
1173 if (capsetp (pid, caps)) {
1174 cap_free (caps);
1175 return -1;
1177 cap_free (caps);
1178 return 0;
1181 static int
1182 jack_set_client_capabilities (jack_engine_t *engine, pid_t cap_pid)
1184 int ret = -1;
1186 /* before sending this request the client has
1187 already checked that the engine has
1188 realtime capabilities, that it is running
1189 realtime and that the pid is defined
1192 if ((ret = give_capabilities (engine, cap_pid)) != 0) {
1193 jack_error ("could not give capabilities to "
1194 "process %d",
1195 cap_pid);
1196 } else {
1197 VERBOSE (engine, "gave capabilities to"
1198 " process %d",
1199 cap_pid);
1202 return ret;
1205 #endif /* USE_CAPABILITIES */
1207 /* perform internal or external client request
1209 * reply_fd is NULL for internal requests
1211 static void
1212 do_request (jack_engine_t *engine, jack_request_t *req, int *reply_fd)
1214 /* The request_lock serializes internal requests (from any
1215 * thread in the server) with external requests (always from "the"
1216 * server thread).
1218 pthread_mutex_lock (&engine->request_lock);
1220 DEBUG ("got a request of type %d", req->type);
1222 switch (req->type) {
1223 case RegisterPort:
1224 req->status = jack_port_do_register (engine, req, reply_fd ? FALSE : TRUE);
1225 break;
1227 case UnRegisterPort:
1228 req->status = jack_port_do_unregister (engine, req);
1229 break;
1231 case ConnectPorts:
1232 req->status = jack_port_do_connect
1233 (engine, req->x.connect.source_port,
1234 req->x.connect.destination_port);
1235 break;
1237 case DisconnectPort:
1238 req->status = jack_port_do_disconnect_all
1239 (engine, req->x.port_info.port_id);
1240 break;
1242 case DisconnectPorts:
1243 req->status = jack_port_do_disconnect
1244 (engine, req->x.connect.source_port,
1245 req->x.connect.destination_port);
1246 break;
1248 case ActivateClient:
1249 req->status = jack_client_activate (engine, req->x.client_id);
1250 break;
1252 case DeactivateClient:
1253 req->status = jack_client_deactivate (engine, req->x.client_id);
1254 break;
1256 case SetTimeBaseClient:
1257 req->status = jack_timebase_set (engine,
1258 req->x.timebase.client_id,
1259 req->x.timebase.conditional);
1260 break;
1262 case ResetTimeBaseClient:
1263 req->status = jack_timebase_reset (engine, req->x.client_id);
1264 break;
1266 case SetSyncClient:
1267 req->status =
1268 jack_transport_client_set_sync (engine,
1269 req->x.client_id);
1270 break;
1272 case ResetSyncClient:
1273 req->status =
1274 jack_transport_client_reset_sync (engine,
1275 req->x.client_id);
1276 break;
1278 case SetSyncTimeout:
1279 req->status = jack_transport_set_sync_timeout (engine,
1280 req->x.timeout);
1281 break;
1283 #ifdef USE_CAPABILITIES
1284 case SetClientCapabilities:
1285 req->status = jack_set_client_capabilities (engine,
1286 req->x.cap_pid);
1287 break;
1288 #endif /* USE_CAPABILITIES */
1290 case GetPortConnections:
1291 case GetPortNConnections:
1292 //JOQ bug: reply_fd may be NULL if internal request
1293 if ((req->status =
1294 jack_do_get_port_connections (engine, req, *reply_fd))
1295 == 0) {
1296 /* we have already replied, don't do it again */
1297 *reply_fd = -1;
1299 break;
1301 case FreeWheel:
1302 req->status = jack_start_freewheeling (engine);
1303 break;
1305 case StopFreeWheel:
1306 req->status = jack_stop_freewheeling (engine);
1307 break;
1309 case SetBufferSize:
1310 req->status = jack_set_buffer_size_request (engine,
1311 req->x.nframes);
1312 break;
1314 case IntClientHandle:
1315 jack_intclient_handle_request (engine, req);
1316 break;
1318 case IntClientLoad:
1319 jack_intclient_load_request (engine, req);
1320 break;
1322 case IntClientName:
1323 jack_intclient_name_request (engine, req);
1324 break;
1326 case IntClientUnload:
1327 jack_intclient_unload_request (engine, req);
1328 break;
1330 case RecomputeTotalLatencies:
1331 jack_lock_graph (engine);
1332 jack_compute_all_port_total_latencies (engine);
1333 jack_unlock_graph (engine);
1334 req->status = 0;
1335 break;
1337 case RecomputeTotalLatency:
1338 jack_lock_graph (engine);
1339 jack_compute_port_total_latency (engine, &engine->control->ports[req->x.port_info.port_id]);
1340 jack_unlock_graph (engine);
1341 req->status = 0;
1342 break;
1344 default:
1345 /* some requests are handled entirely on the client
1346 * side, by adjusting the shared memory area(s) */
1347 break;
1350 pthread_mutex_unlock (&engine->request_lock);
1352 DEBUG ("status of request: %d", req->status);
1356 internal_client_request (void* ptr, jack_request_t *request)
1358 do_request ((jack_engine_t*) ptr, request, NULL);
1359 return request->status;
1362 static int
1363 handle_external_client_request (jack_engine_t *engine, int fd)
1365 /* CALLER holds read lock on graph */
1367 jack_request_t req;
1368 jack_client_internal_t *client = 0;
1369 int reply_fd;
1370 JSList *node;
1371 ssize_t r;
1373 for (node = engine->clients; node; node = jack_slist_next (node)) {
1374 if (((jack_client_internal_t *) node->data)->request_fd == fd) {
1375 client = (jack_client_internal_t *) node->data;
1376 break;
1380 if (client == NULL) {
1381 jack_error ("client input on unknown fd %d!", fd);
1382 return -1;
1385 if ((r = read (client->request_fd, &req, sizeof (req)))
1386 < (ssize_t) sizeof (req)) {
1387 if (r == 0) {
1388 #ifdef JACK_USE_MACH_THREADS
1389 /* poll is implemented using
1390 select (see the macosx/fakepoll
1391 code). When the socket is closed
1392 select does not return any error,
1393 POLLIN is true and the next read
1394 will return 0 bytes. This
1395 behaviour is diffrent from the
1396 Linux poll behaviour. Thus we use
1397 this condition as a socket error
1398 and remove the client.
1400 jack_mark_client_socket_error (engine, fd);
1401 #endif /* JACK_USE_MACH_THREADS */
1402 return 1;
1403 } else {
1404 jack_error ("cannot read request from client (%d/%d/%s)",
1405 r, sizeof(req), strerror (errno));
1406 // XXX: shouldnt we mark this client as error now ?
1408 return -1;
1412 reply_fd = client->request_fd;
1414 jack_unlock_graph (engine);
1415 do_request (engine, &req, &reply_fd);
1416 jack_lock_graph (engine);
1418 if (reply_fd >= 0) {
1419 DEBUG ("replying to client");
1420 if (write (reply_fd, &req, sizeof (req))
1421 < (ssize_t) sizeof (req)) {
1422 jack_error ("cannot write request result to client");
1423 return -1;
1425 } else {
1426 DEBUG ("*not* replying to client");
1429 return 0;
1432 static int
1433 handle_client_ack_connection (jack_engine_t *engine, int client_fd)
1435 jack_client_internal_t *client;
1436 jack_client_connect_ack_request_t req;
1437 jack_client_connect_ack_result_t res;
1439 if (read (client_fd, &req, sizeof (req)) != sizeof (req)) {
1440 jack_error ("cannot read ACK connection request from client");
1441 return -1;
1444 if ((client = jack_client_internal_by_id (engine, req.client_id))
1445 == NULL) {
1446 jack_error ("unknown client ID in ACK connection request");
1447 return -1;
1450 client->event_fd = client_fd;
1451 VERBOSE (engine, "new client %s using %d for events", client->control->name,
1452 client->event_fd);
1454 res.status = 0;
1456 if (write (client->event_fd, &res, sizeof (res)) != sizeof (res)) {
1457 jack_error ("cannot write ACK connection response to client");
1458 return -1;
1461 return 0;
1465 static void *
1466 jack_server_thread (void *arg)
1469 jack_engine_t *engine = (jack_engine_t *) arg;
1470 struct sockaddr_un client_addr;
1471 socklen_t client_addrlen;
1472 int problemsProblemsPROBLEMS = 0;
1473 int client_socket;
1474 int done = 0;
1475 int i;
1476 const int fixed_fd_cnt = 3;
1478 while (!done) {
1479 JSList* node;
1480 int clients;
1482 jack_rdlock_graph (engine);
1484 clients = jack_slist_length (engine->clients);
1486 if (engine->pfd_size < fixed_fd_cnt + clients) {
1487 if (engine->pfd) {
1488 free (engine->pfd);
1490 engine->pfd = (struct pollfd *) malloc (sizeof(struct pollfd) * (fixed_fd_cnt + clients));
1493 engine->pfd[0].fd = engine->fds[0];
1494 engine->pfd[0].events = POLLIN|POLLERR;
1495 engine->pfd[1].fd = engine->fds[1];
1496 engine->pfd[1].events = POLLIN|POLLERR;
1497 engine->pfd[2].fd = engine->cleanup_fifo[0];
1498 engine->pfd[2].events = POLLIN|POLLERR;
1499 engine->pfd_max = fixed_fd_cnt;
1501 for (node = engine->clients; node; node = node->next) {
1503 jack_client_internal_t* client = (jack_client_internal_t*)(node->data);
1505 if (client->request_fd < 0 || client->control->dead || client->error >= JACK_ERROR_WITH_SOCKETS) {
1506 continue;
1508 engine->pfd[engine->pfd_max].fd = client->request_fd;
1509 engine->pfd[engine->pfd_max].events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
1510 engine->pfd_max++;
1513 jack_unlock_graph (engine);
1515 VERBOSE (engine, "start poll on %d fd's", engine->pfd_max);
1517 /* go to sleep for a long, long time, or until a request
1518 arrives, or until a communication channel is broken
1521 if (poll (engine->pfd, engine->pfd_max, -1) < 0) {
1522 if (errno == EINTR) {
1523 continue;
1525 jack_error ("poll failed (%s)", strerror (errno));
1526 break;
1529 VERBOSE(engine, "server thread back from poll");
1531 /* Stephane Letz: letz@grame.fr : has to be added
1532 * otherwise pthread_cancel() does not work on MacOSX */
1533 pthread_testcancel();
1536 /* empty cleanup FIFO if necessary */
1538 if (engine->pfd[2].revents & ~POLLIN) {
1539 /* time to die */
1540 break;
1543 if (engine->pfd[2].revents & POLLIN) {
1544 char c;
1545 while (read (engine->cleanup_fifo[0], &c, 1) == 1);
1548 /* check each client socket before handling other request*/
1550 jack_rdlock_graph (engine);
1552 for (i = fixed_fd_cnt; i < engine->pfd_max; i++) {
1554 if (engine->pfd[i].fd < 0) {
1555 continue;
1558 if (engine->pfd[i].revents & ~POLLIN) {
1560 jack_mark_client_socket_error (engine, engine->pfd[i].fd);
1561 jack_lock_problems (engine);
1562 engine->problems++;
1563 jack_unlock_problems (engine);
1565 } else if (engine->pfd[i].revents & POLLIN) {
1567 if (handle_external_client_request (engine, engine->pfd[i].fd)) {
1568 jack_error ("could not handle external"
1569 " client request");
1570 jack_lock_problems (engine);
1571 engine->problems++;
1572 jack_unlock_problems (engine);
1577 problemsProblemsPROBLEMS = engine->problems;
1579 jack_unlock_graph (engine);
1581 /* need to take write lock since we may/will rip out some clients,
1582 and reset engine->problems
1585 if (problemsProblemsPROBLEMS) {
1586 jack_lock_graph (engine);
1587 jack_lock_problems (engine);
1588 VERBOSE (engine, "we have problem clients");
1589 jack_remove_clients (engine);
1590 engine->problems = 0;
1591 jack_unlock_problems (engine);
1592 jack_unlock_graph (engine);
1596 /* check the master server socket */
1598 if (engine->pfd[0].revents & POLLERR) {
1599 jack_error ("error on server socket");
1600 break;
1603 if (engine->control->engine_ok && engine->pfd[0].revents & POLLIN) {
1604 DEBUG ("pfd[0].revents & POLLIN");
1606 memset (&client_addr, 0, sizeof (client_addr));
1607 client_addrlen = sizeof (client_addr);
1609 if ((client_socket =
1610 accept (engine->fds[0],
1611 (struct sockaddr *) &client_addr,
1612 &client_addrlen)) < 0) {
1613 jack_error ("cannot accept new connection (%s)",
1614 strerror (errno));
1615 } else if (jack_client_create (engine, client_socket) < 0) {
1616 jack_error ("cannot complete client "
1617 "connection process");
1618 close (client_socket);
1622 /* check the ACK server socket */
1624 if (engine->pfd[1].revents & POLLERR) {
1625 jack_error ("error on server ACK socket");
1626 break;
1629 if (engine->control->engine_ok && engine->pfd[1].revents & POLLIN) {
1630 DEBUG ("pfd[1].revents & POLLIN");
1632 memset (&client_addr, 0, sizeof (client_addr));
1633 client_addrlen = sizeof (client_addr);
1635 if ((client_socket =
1636 accept (engine->fds[1],
1637 (struct sockaddr *) &client_addr,
1638 &client_addrlen)) < 0) {
1639 jack_error ("cannot accept new ACK connection"
1640 " (%s)", strerror (errno));
1641 } else if (handle_client_ack_connection
1642 (engine, client_socket)) {
1643 jack_error ("cannot complete client ACK "
1644 "connection process");
1645 close (client_socket);
1650 return 0;
1653 jack_engine_t *
1654 jack_engine_new (int realtime, int rtpriority, int do_mlock, int do_unlock,
1655 const char *server_name, int temporary, int verbose,
1656 int client_timeout, unsigned int port_max, pid_t wait_pid,
1657 jack_nframes_t frame_time_offset, int nozombies, JSList *drivers)
1659 jack_engine_t *engine;
1660 unsigned int i;
1661 char server_dir[PATH_MAX+1] = "";
1663 #ifdef USE_CAPABILITIES
1664 uid_t uid = getuid ();
1665 uid_t euid = geteuid ();
1666 #endif /* USE_CAPABILITIES */
1668 /* before we start allocating resources, make sure that if realtime was requested that we can
1669 actually do it.
1672 if (realtime) {
1673 if (jack_acquire_real_time_scheduling (pthread_self(), 10) != 0) {
1674 /* can't run realtime - time to bomb */
1675 return NULL;
1678 jack_drop_real_time_scheduling (pthread_self());
1680 #ifdef USE_MLOCK
1682 if (do_mlock && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) {
1683 jack_error ("cannot lock down memory for jackd (%s)",
1684 strerror (errno));
1685 #ifdef ENSURE_MLOCK
1686 return NULL;
1687 #endif /* ENSURE_MLOCK */
1689 #endif /* USE_MLOCK */
1692 /* start a thread to display messages from realtime threads */
1693 jack_messagebuffer_init();
1695 jack_init_time ();
1697 /* allocate the engine, zero the structure to ease debugging */
1698 engine = (jack_engine_t *) calloc (1, sizeof (jack_engine_t));
1700 engine->drivers = drivers;
1701 engine->driver = NULL;
1702 engine->driver_desc = NULL;
1703 engine->driver_params = NULL;
1705 engine->set_sample_rate = jack_set_sample_rate;
1706 engine->set_buffer_size = jack_driver_buffer_size;
1707 engine->run_cycle = jack_run_cycle;
1708 engine->delay = jack_engine_delay;
1709 engine->driver_exit = jack_engine_driver_exit;
1710 engine->transport_cycle_start = jack_transport_cycle_start;
1711 engine->client_timeout_msecs = client_timeout;
1712 engine->problems = 0;
1714 engine->next_client_id = 1; /* 0 is a NULL client ID */
1715 engine->port_max = port_max;
1716 engine->server_thread = 0;
1717 engine->watchdog_thread = 0;
1718 engine->rtpriority = rtpriority;
1719 engine->silent_buffer = 0;
1720 engine->verbose = verbose;
1721 engine->server_name = server_name;
1722 engine->temporary = temporary;
1723 engine->freewheeling = 0;
1724 engine->feedbackcount = 0;
1725 engine->wait_pid = wait_pid;
1726 engine->nozombies = nozombies;
1727 engine->removing_clients = 0;
1729 engine->audio_out_cnt = 0;
1730 engine->audio_in_cnt = 0;
1731 engine->midi_out_cnt = 0;
1732 engine->midi_in_cnt = 0;
1734 jack_engine_reset_rolling_usecs (engine);
1735 engine->max_usecs = 0.0f;
1737 pthread_rwlock_init (&engine->client_lock, 0);
1738 pthread_mutex_init (&engine->port_lock, 0);
1739 pthread_mutex_init (&engine->request_lock, 0);
1740 pthread_mutex_init (&engine->problem_lock, 0);
1742 engine->clients = 0;
1744 engine->pfd_size = 0;
1745 engine->pfd_max = 0;
1746 engine->pfd = 0;
1748 engine->fifo_size = 16;
1749 engine->fifo = (int *) malloc (sizeof (int) * engine->fifo_size);
1750 for (i = 0; i < engine->fifo_size; i++) {
1751 engine->fifo[i] = -1;
1754 if (pipe (engine->cleanup_fifo)) {
1755 jack_error ("cannot create cleanup FIFOs (%s)", strerror (errno));
1756 return NULL;
1759 if (fcntl (engine->cleanup_fifo[0], F_SETFL, O_NONBLOCK)) {
1760 jack_error ("cannot set O_NONBLOCK on cleanup read FIFO (%s)", strerror (errno));
1761 return NULL;
1764 if (fcntl (engine->cleanup_fifo[1], F_SETFL, O_NONBLOCK)) {
1765 jack_error ("cannot set O_NONBLOCK on cleanup write FIFO (%s)", strerror (errno));
1766 return NULL;
1769 engine->external_client_cnt = 0;
1771 srandom (time ((time_t *) 0));
1773 if (jack_shmalloc (sizeof (jack_control_t)
1774 + ((sizeof (jack_port_shared_t) * engine->port_max)),
1775 &engine->control_shm)) {
1776 jack_error ("cannot create engine control shared memory "
1777 "segment (%s)", strerror (errno));
1778 return NULL;
1781 if (jack_attach_shm (&engine->control_shm)) {
1782 jack_error ("cannot attach to engine control shared memory"
1783 " (%s)", strerror (errno));
1784 jack_destroy_shm (&engine->control_shm);
1785 return NULL;
1788 engine->control = (jack_control_t *)
1789 jack_shm_addr (&engine->control_shm);
1791 /* Setup port type information from builtins. buffer space is
1792 * allocated when the driver calls jack_driver_buffer_size().
1794 for (i = 0; jack_builtin_port_types[i].type_name[0]; ++i) {
1796 memcpy (&engine->control->port_types[i],
1797 &jack_builtin_port_types[i],
1798 sizeof (jack_port_type_info_t));
1800 VERBOSE (engine, "registered builtin port type %s",
1801 engine->control->port_types[i].type_name);
1803 /* the port type id is index into port_types array */
1804 engine->control->port_types[i].ptype_id = i;
1806 /* be sure to initialize mutex correctly */
1807 pthread_mutex_init (&engine->port_buffers[i].lock, NULL);
1809 /* set buffer list info correctly */
1810 engine->port_buffers[i].freelist = NULL;
1811 engine->port_buffers[i].info = NULL;
1813 /* mark each port segment as not allocated */
1814 engine->port_segment[i].index = -1;
1815 engine->port_segment[i].attached_at = 0;
1818 engine->control->n_port_types = i;
1820 /* Mark all ports as available */
1822 for (i = 0; i < engine->port_max; i++) {
1823 engine->control->ports[i].in_use = 0;
1824 engine->control->ports[i].id = i;
1825 engine->control->ports[i].alias1[0] = '\0';
1826 engine->control->ports[i].alias2[0] = '\0';
1829 /* allocate internal port structures so that we can keep track
1830 * of port connections.
1832 engine->internal_ports = (jack_port_internal_t *)
1833 malloc (sizeof (jack_port_internal_t) * engine->port_max);
1835 for (i = 0; i < engine->port_max; i++) {
1836 engine->internal_ports[i].connections = 0;
1839 if (make_sockets (engine->server_name, engine->fds) < 0) {
1840 jack_error ("cannot create server sockets");
1841 return NULL;
1844 engine->control->port_max = engine->port_max;
1845 engine->control->real_time = realtime;
1846 engine->control->client_priority = (realtime
1847 ? engine->rtpriority - 1
1848 : 0);
1849 engine->control->do_mlock = do_mlock;
1850 engine->control->do_munlock = do_unlock;
1851 engine->control->cpu_load = 0;
1852 engine->control->xrun_delayed_usecs = 0;
1853 engine->control->max_delayed_usecs = 0;
1855 jack_set_clock_source (clock_source);
1856 engine->control->clock_source = clock_source;
1858 VERBOSE (engine, "clock source = %s", jack_clock_source_name (clock_source));
1860 engine->control->frame_timer.frames = frame_time_offset;
1861 engine->control->frame_timer.reset_pending = 0;
1862 engine->control->frame_timer.current_wakeup = 0;
1863 engine->control->frame_timer.next_wakeup = 0;
1864 engine->control->frame_timer.initialized = 0;
1865 engine->control->frame_timer.filter_coefficient = 0.01;
1866 engine->control->frame_timer.second_order_integrator = 0;
1868 engine->first_wakeup = 1;
1870 engine->control->buffer_size = 0;
1871 jack_transport_init (engine);
1872 jack_set_sample_rate (engine, 0);
1873 engine->control->internal = 0;
1875 engine->control->has_capabilities = 0;
1877 #ifdef JACK_USE_MACH_THREADS
1878 /* specific resources for server/client real-time thread
1879 * communication */
1880 engine->servertask = mach_task_self();
1881 if (task_get_bootstrap_port(engine->servertask, &engine->bp)){
1882 jack_error("Jackd: Can't find bootstrap mach port");
1883 return NULL;
1885 engine->portnum = 0;
1886 #endif /* JACK_USE_MACH_THREADS */
1889 #ifdef USE_CAPABILITIES
1890 if (uid == 0 || euid == 0) {
1891 VERBOSE (engine, "running with uid=%d and euid=%d, "
1892 "will not try to use capabilites",
1893 uid, euid);
1894 } else {
1895 /* only try to use capabilities if not running as root */
1896 engine->control->has_capabilities = check_capabilities (engine);
1897 if (engine->control->has_capabilities == 0) {
1898 VERBOSE (engine, "required capabilities not "
1899 "available");
1901 if (engine->verbose) {
1902 size_t size;
1903 cap_t cap = cap_init();
1904 capgetp(0, cap);
1905 VERBOSE (engine, "capabilities: %s",
1906 cap_to_text(cap, &size));
1909 #endif /* USE_CAPABILITIES */
1911 engine->control->engine_ok = 1;
1913 snprintf (engine->fifo_prefix, sizeof (engine->fifo_prefix),
1914 "%s/jack-ack-fifo-%d",
1915 jack_server_dir (engine->server_name, server_dir), getpid ());
1917 (void) jack_get_fifo_fd (engine, 0);
1919 jack_client_create_thread (NULL, &engine->server_thread, 0, FALSE,
1920 &jack_server_thread, engine);
1922 return engine;
1925 static void
1926 jack_engine_delay (jack_engine_t *engine, float delayed_usecs)
1928 jack_event_t event;
1930 engine->control->frame_timer.reset_pending = 1;
1932 engine->control->xrun_delayed_usecs = delayed_usecs;
1934 if (delayed_usecs > engine->control->max_delayed_usecs)
1935 engine->control->max_delayed_usecs = delayed_usecs;
1937 event.type = XRun;
1939 jack_deliver_event_to_all (engine, &event);
1942 static inline void
1943 jack_inc_frame_time (jack_engine_t *engine, jack_nframes_t nframes)
1945 jack_frame_timer_t *timer = &engine->control->frame_timer;
1946 jack_time_t now = engine->driver->last_wait_ust; // effective time
1947 float delta;
1949 // really need a memory barrier here
1950 timer->guard1++;
1952 delta = (int64_t) now - (int64_t) timer->next_wakeup;
1954 timer->current_wakeup = timer->next_wakeup;
1955 timer->frames += nframes;
1956 timer->second_order_integrator += 0.5f *
1957 timer->filter_coefficient * delta;
1958 timer->next_wakeup = timer->current_wakeup +
1959 engine->driver->period_usecs +
1960 (int64_t) floorf ((timer->filter_coefficient *
1961 (delta + timer->second_order_integrator)));
1962 timer->initialized = 1;
1964 // might need a memory barrier here
1965 timer->guard2++;
1968 static void*
1969 jack_engine_freewheel (void *arg)
1971 jack_engine_t* engine = (jack_engine_t *) arg;
1973 VERBOSE (engine, "freewheel thread starting ...");
1975 /* we should not be running SCHED_FIFO, so we don't
1976 have to do anything about scheduling.
1979 while (engine->freewheeling) {
1981 jack_lock_graph (engine);
1983 if (jack_engine_process (engine,
1984 engine->control->buffer_size)) {
1985 jack_error ("process cycle within freewheel failed");
1986 jack_unlock_graph (engine);
1987 break;
1990 jack_unlock_graph (engine);
1993 VERBOSE (engine, "freewheel came to an end, naturally");
1994 return 0;
1997 static int
1998 jack_start_freewheeling (jack_engine_t* engine)
2000 jack_event_t event;
2002 if (engine->freewheeling) {
2003 return 0;
2006 if (engine->driver == NULL) {
2007 jack_error ("cannot start freewheeling without a driver!");
2008 return -1;
2011 /* stop driver before telling anyone about it so
2012 there are no more process() calls being handled.
2015 if (engine->driver->stop (engine->driver)) {
2016 jack_error ("could not stop driver for freewheeling");
2017 return -1;
2020 engine->freewheeling = 1;
2022 event.type = StartFreewheel;
2023 jack_deliver_event_to_all (engine, &event);
2025 if (jack_client_create_thread (NULL, &engine->freewheel_thread, 0, FALSE,
2026 jack_engine_freewheel, engine)) {
2027 jack_error ("could not start create freewheel thread");
2028 return -1;
2031 return 0;
2034 static int
2035 jack_stop_freewheeling (jack_engine_t* engine)
2037 jack_event_t event;
2038 void *ftstatus;
2040 if (!engine->freewheeling) {
2041 return 0;
2044 if (engine->driver == NULL) {
2045 jack_error ("cannot start freewheeling without a driver!");
2046 return -1;
2049 if (!engine->freewheeling) {
2050 VERBOSE (engine, "stop freewheel when not freewheeling");
2051 return 0;
2054 /* tell the freewheel thread to stop, and wait for it
2055 to exit.
2058 engine->freewheeling = 0;
2059 VERBOSE (engine, "freewheeling stopped, waiting for thread");
2060 pthread_join (engine->freewheel_thread, &ftstatus);
2061 VERBOSE (engine, "freewheel thread has returned");
2063 /* tell everyone we've stopped */
2065 event.type = StopFreewheel;
2066 jack_deliver_event_to_all (engine, &event);
2068 /* restart the driver */
2070 if (engine->driver->start (engine->driver)) {
2071 jack_error ("could not restart driver after freewheeling");
2072 return -1;
2074 return 0;
2077 static int
2078 jack_run_one_cycle (jack_engine_t *engine, jack_nframes_t nframes,
2079 float delayed_usecs)
2081 jack_driver_t* driver = engine->driver;
2082 int ret = -1;
2083 static int consecutive_excessive_delays = 0;
2085 #define WORK_SCALE 1.0f
2087 if (engine->control->real_time &&
2088 engine->spare_usecs &&
2089 ((WORK_SCALE * engine->spare_usecs) <= delayed_usecs)) {
2091 MESSAGE("delay of %.3f usecs exceeds estimated spare"
2092 " time of %.3f; restart ...\n",
2093 delayed_usecs, WORK_SCALE * engine->spare_usecs);
2095 if (++consecutive_excessive_delays > 10) {
2096 jack_error ("too many consecutive interrupt delays "
2097 "... engine pausing");
2098 return -1; /* will exit the thread loop */
2101 jack_engine_delay (engine, delayed_usecs);
2103 return 0;
2105 } else {
2106 consecutive_excessive_delays = 0;
2109 DEBUG ("trying to acquire read lock");
2110 if (jack_try_rdlock_graph (engine)) {
2111 /* engine can't run. just throw away an entire cycle */
2112 VERBOSE (engine, "null cycle");
2113 driver->null_cycle (driver, nframes);
2114 return 0;
2117 if (engine->problems) {
2118 /* engine can't run. just throw away an entire cycle */
2119 VERBOSE (engine, "problem-driven null cycle");
2120 jack_unlock_graph (engine);
2121 driver->null_cycle (driver, nframes);
2122 return 0;
2125 if (!engine->freewheeling) {
2126 DEBUG("waiting for driver read\n");
2127 if (driver->read (driver, nframes)) {
2128 goto unlock;
2132 DEBUG("run process\n");
2134 if (jack_engine_process (engine, nframes) == 0) {
2135 if (!engine->freewheeling) {
2136 if (driver->write (driver, nframes)) {
2137 goto unlock;
2141 } else {
2143 JSList *node;
2144 DEBUG ("engine process cycle failed");
2146 /* we are already late, or something else went wrong,
2147 so it can't hurt to check the existence of all
2148 clients.
2151 for (node = engine->clients; node;
2152 node = jack_slist_next (node)) {
2153 jack_client_internal_t *client =
2154 (jack_client_internal_t *) node->data;
2156 if (client->control->type == ClientExternal) {
2157 if (kill (client->control->pid, 0)) {
2158 VERBOSE(engine,
2159 "client %s has died/exited",
2160 client->control->name);
2161 client->error++;
2163 if(client->control->last_status != 0) {
2164 VERBOSE(engine,
2165 "client %s has nonzero process callback status (%d)\n",
2166 client->control->name, client->control->last_status);
2167 client->error++;
2171 DEBUG ("client %s errors = %d", client->control->name,
2172 client->error);
2176 jack_engine_post_process (engine);
2178 if (delayed_usecs > engine->control->max_delayed_usecs)
2179 engine->control->max_delayed_usecs = delayed_usecs;
2181 ret = 0;
2183 unlock:
2184 jack_unlock_graph (engine);
2185 DEBUG("cycle finished, status = %d", ret);
2187 return ret;
2190 static void
2191 jack_engine_driver_exit (jack_engine_t* engine)
2193 jack_driver_t* driver = engine->driver;
2195 VERBOSE (engine, "stopping driver");
2196 driver->stop (driver);
2197 VERBOSE (engine, "detaching driver");
2198 driver->detach (driver, engine);
2200 /* tell anyone waiting that the driver exited. */
2201 kill (engine->wait_pid, SIGUSR2);
2203 engine->driver = NULL;
2206 static int
2207 jack_run_cycle (jack_engine_t *engine, jack_nframes_t nframes,
2208 float delayed_usecs)
2210 jack_nframes_t left;
2211 jack_nframes_t b_size = engine->control->buffer_size;
2212 jack_frame_timer_t* timer = &engine->control->frame_timer;
2213 int no_increment = 0;
2215 if (engine->first_wakeup) {
2217 /* the first wakeup */
2219 timer->next_wakeup =
2220 engine->driver->last_wait_ust +
2221 engine->driver->period_usecs;
2222 engine->first_wakeup = 0;
2224 /* if we got an xrun/delayed wakeup on the first cycle,
2225 reset the pending flag (we have no predicted wakeups
2226 to use), but avoid incrementing the frame timer.
2229 if (timer->reset_pending) {
2230 timer->reset_pending = 0;
2231 no_increment = 1;
2235 if (timer->reset_pending) {
2237 /* post xrun-handling */
2239 /* don't bother to increment the frame counter, because we missed 1 or more
2240 deadlines in the backend anyway.
2243 timer->current_wakeup = engine->driver->last_wait_ust;
2244 timer->next_wakeup = engine->driver->last_wait_ust +
2245 engine->driver->period_usecs;
2247 timer->reset_pending = 0;
2249 } else {
2251 /* normal condition */
2253 if (!no_increment) {
2254 jack_inc_frame_time (engine, nframes);
2258 if (engine->verbose) {
2259 if (nframes != b_size) {
2260 VERBOSE (engine,
2261 "late driver wakeup: nframes to process = %"
2262 PRIu32 ".", nframes);
2266 /* run as many cycles as it takes to consume nframes */
2267 for (left = nframes; left >= b_size; left -= b_size) {
2268 if (jack_run_one_cycle (engine, b_size, delayed_usecs)) {
2269 jack_error ("cycle execution failure, exiting");
2270 return EIO;
2274 return 0;
2277 void
2278 jack_engine_delete (jack_engine_t *engine)
2280 int i;
2282 if (engine == NULL)
2283 return;
2285 VERBOSE (engine, "starting server engine shutdown");
2287 engine->control->engine_ok = 0; /* tell clients we're going away */
2289 /* this will wake the server thread and cause it to exit */
2291 close (engine->cleanup_fifo[0]);
2292 close (engine->cleanup_fifo[1]);
2294 /* shutdown master socket to prevent new clients arriving */
2295 shutdown (engine->fds[0], SHUT_RDWR);
2296 // close (engine->fds[0]);
2298 /* now really tell them we're going away */
2300 for (i = 0; i < engine->pfd_max; ++i) {
2301 shutdown (engine->pfd[i].fd, SHUT_RDWR);
2304 if (engine->driver) {
2305 jack_driver_t* driver = engine->driver;
2307 VERBOSE (engine, "stopping driver");
2308 driver->stop (driver);
2309 // VERBOSE (engine, "detaching driver");
2310 // driver->detach (driver, engine);
2311 VERBOSE (engine, "unloading driver");
2312 jack_driver_unload (driver);
2313 engine->driver = NULL;
2316 VERBOSE (engine, "freeing shared port segments");
2317 for (i = 0; i < engine->control->n_port_types; ++i) {
2318 jack_release_shm (&engine->port_segment[i]);
2319 jack_destroy_shm (&engine->port_segment[i]);
2322 /* stop the other engine threads */
2323 VERBOSE (engine, "stopping server thread");
2325 #if JACK_USE_MACH_THREADS
2326 // MacOSX pthread_cancel still not implemented correctly in Darwin
2327 mach_port_t machThread = pthread_mach_thread_np (engine->server_thread);
2328 thread_terminate (machThread);
2329 #else
2330 pthread_cancel (engine->server_thread);
2331 pthread_join (engine->server_thread, NULL);
2332 #endif
2334 #ifndef JACK_USE_MACH_THREADS
2335 /* Cancel the watchdog thread and wait for it to terminate.
2337 * The watchdog thread is not used on MacOSX since CoreAudio
2338 * drivers already contain a similar mechanism.
2340 if (engine->control->real_time && engine->watchdog_thread) {
2341 VERBOSE (engine, "stopping watchdog thread");
2342 pthread_cancel (engine->watchdog_thread);
2343 pthread_join (engine->watchdog_thread, NULL);
2345 #endif
2347 VERBOSE (engine, "last xrun delay: %.3f usecs",
2348 engine->control->xrun_delayed_usecs);
2349 VERBOSE (engine, "max delay reported by backend: %.3f usecs",
2350 engine->control->max_delayed_usecs);
2352 /* free engine control shm segment */
2353 engine->control = NULL;
2354 VERBOSE (engine, "freeing engine shared memory");
2355 jack_release_shm (&engine->control_shm);
2356 jack_destroy_shm (&engine->control_shm);
2358 VERBOSE (engine, "max usecs: %.3f, engine deleted", engine->max_usecs);
2360 free (engine);
2362 jack_messagebuffer_exit();
2365 void
2366 jack_port_clear_connections (jack_engine_t *engine,
2367 jack_port_internal_t *port)
2369 JSList *node, *next;
2371 for (node = port->connections; node; ) {
2372 next = jack_slist_next (node);
2373 jack_port_disconnect_internal (
2374 engine, ((jack_connection_internal_t *)
2375 node->data)->source,
2376 ((jack_connection_internal_t *)
2377 node->data)->destination);
2378 node = next;
2381 jack_slist_free (port->connections);
2382 port->connections = 0;
2385 static void
2386 jack_deliver_event_to_all (jack_engine_t *engine, jack_event_t *event)
2388 JSList *node;
2390 jack_rdlock_graph (engine);
2391 for (node = engine->clients; node; node = jack_slist_next (node)) {
2392 jack_deliver_event (engine,
2393 (jack_client_internal_t *) node->data,
2394 event);
2396 jack_unlock_graph (engine);
2399 static void
2400 jack_notify_all_port_interested_clients (jack_engine_t *engine, jack_client_id_t src, jack_client_id_t dst, jack_port_id_t a, jack_port_id_t b, int connected)
2402 JSList *node;
2403 jack_event_t event;
2405 event.type = (connected ? PortConnected : PortDisconnected);
2406 event.x.self_id = a;
2407 event.y.other_id = b;
2409 /* GRAPH MUST BE LOCKED : see callers of jack_send_connection_notification()
2412 jack_client_internal_t* src_client = jack_client_internal_by_id (engine, src);
2413 jack_client_internal_t* dst_client = jack_client_internal_by_id (engine, dst);
2415 for (node = engine->clients; node; node = jack_slist_next (node)) {
2416 jack_client_internal_t* client = (jack_client_internal_t*) node->data;
2417 if (src_client != client && dst_client != client && client->control->port_connect_cbset != FALSE) {
2419 /* one of the ports belong to this client or it has a port connect callback */
2420 jack_deliver_event (engine, client, &event);
2425 static int
2426 jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client,
2427 jack_event_t *event)
2429 char status;
2431 /* caller must hold the graph lock */
2433 DEBUG ("delivering event (type %d)", event->type);
2435 /* we are not RT-constrained here, so use kill(2) to beef up
2436 our check on a client's continued well-being
2439 if (client->control->dead || client->error >= JACK_ERROR_WITH_SOCKETS
2440 || (client->control->type == ClientExternal && kill (client->control->pid, 0))) {
2441 DEBUG ("client %s is dead - no event sent",
2442 client->control->name);
2443 return 0;
2446 DEBUG ("client %s is still alive", client->control->name);
2448 if (jack_client_is_internal (client)) {
2450 switch (event->type) {
2451 case PortConnected:
2452 case PortDisconnected:
2453 jack_client_handle_port_connection
2454 (client->private_client, event);
2455 break;
2457 case BufferSizeChange:
2458 jack_client_invalidate_port_buffers
2459 (client->private_client);
2461 if (client->control->bufsize_cbset) {
2462 client->private_client->bufsize
2463 (event->x.n,
2464 client->private_client->bufsize_arg);
2466 break;
2468 case SampleRateChange:
2469 if (client->control->srate_cbset) {
2470 client->private_client->srate
2471 (event->x.n,
2472 client->private_client->srate_arg);
2474 break;
2476 case GraphReordered:
2477 if (client->control->graph_order_cbset) {
2478 client->private_client->graph_order
2479 (client->private_client->graph_order_arg);
2481 break;
2483 case XRun:
2484 if (client->control->xrun_cbset) {
2485 client->private_client->xrun
2486 (client->private_client->xrun_arg);
2488 break;
2490 default:
2491 /* internal clients don't need to know */
2492 break;
2495 } else {
2497 if (client->control->active) {
2499 /* there's a thread waiting for events, so
2500 * it's worth telling the client */
2502 DEBUG ("engine writing on event fd");
2504 if (write (client->event_fd, event, sizeof (*event))
2505 != sizeof (*event)) {
2506 jack_error ("cannot send event to client [%s]"
2507 " (%s)", client->control->name,
2508 strerror (errno));
2509 client->error += JACK_ERROR_WITH_SOCKETS;
2510 jack_lock_problems (engine);
2511 engine->problems++;
2512 jack_unlock_problems (engine);
2515 if (client->error) {
2516 status = 1;
2517 } else {
2518 // then we check whether there really is an error.... :)
2520 struct pollfd pfd[1];
2521 pfd[0].fd = client->event_fd;
2522 pfd[0].events = POLLERR|POLLIN|POLLHUP|POLLNVAL;
2523 jack_time_t poll_timeout = JACKD_CLIENT_EVENT_TIMEOUT;
2524 int poll_ret;
2525 jack_time_t then = jack_get_microseconds ();
2526 jack_time_t now;
2528 #ifdef __linux
2529 again:
2530 #endif
2531 VERBOSE(engine,"client event poll on %d for %s starts at %lld",
2532 client->event_fd, client->control->name, then);
2533 if ((poll_ret = poll (pfd, 1, poll_timeout)) < 0) {
2534 DEBUG ("client event poll not ok! (-1) poll returned an error");
2535 jack_error ("poll on subgraph processing failed (%s)", strerror (errno));
2536 status = -1;
2537 } else {
2539 DEBUG ("\n\n\n\n\n back from client event poll, revents = 0x%x\n\n\n", pfd[0].revents);
2540 now = jack_get_microseconds();
2541 VERBOSE(engine,"back from client event poll after %lld usecs", now - then);
2543 if (pfd[0].revents & ~POLLIN) {
2545 /* some kind of OOB socket event */
2547 DEBUG ("client event poll not ok! (-2), revents = %d\n", pfd[0].revents);
2548 jack_error ("subgraph starting at %s lost client", client->control->name);
2549 status = -2;
2551 } else if (pfd[0].revents & POLLIN) {
2553 /* client responded normally */
2555 DEBUG ("client event poll ok!");
2556 status = 0;
2558 } else if (poll_ret == 0) {
2560 /* no events, no errors, we woke up because poll()
2561 decided that time was up ...
2564 #ifdef __linux
2565 if (linux_poll_bug_encountered (engine, then, &poll_timeout)) {
2566 goto again;
2569 if (poll_timeout < 200) {
2570 VERBOSE (engine, "FALSE WAKEUP skipped, remaining = %lld usec", poll_timeout);
2571 status = 0;
2572 } else {
2573 #endif
2574 DEBUG ("client event poll not ok! (1 = poll timed out, revents = 0x%04x, poll_ret = %d)", pfd[0].revents, poll_ret);
2575 VERBOSE (engine,"client %s did not respond to event type %d in time"
2576 "(fd=%d, revents = 0x%04x, timeout was %lld)",
2577 client->control->name, event->type,
2578 client->event_fd,
2579 pfd[0].revents,
2580 poll_timeout);
2581 status = 1;
2582 #ifdef __linux
2584 #endif
2589 if (status == 0) {
2590 if (read (client->event_fd, &status, sizeof (status)) != sizeof (status)) {
2591 jack_error ("cannot read event response from "
2592 "client [%s] (%s)",
2593 client->control->name,
2594 strerror (errno));
2595 client->error += JACK_ERROR_WITH_SOCKETS;
2596 jack_lock_problems (engine);
2597 engine->problems++;
2598 jack_unlock_problems (engine);
2600 } else {
2601 jack_error ("bad status (%d) for client %s "
2602 "handling event (type = %d)",
2603 status,
2604 client->control->name,
2605 event->type);
2606 client->error += JACK_ERROR_WITH_SOCKETS;
2607 jack_lock_problems (engine);
2608 engine->problems++;
2609 jack_unlock_problems (engine);
2613 DEBUG ("event delivered");
2615 return 0;
2619 jack_rechain_graph (jack_engine_t *engine)
2621 JSList *node, *next;
2622 unsigned long n;
2623 int err = 0;
2624 jack_client_internal_t *client, *subgraph_client, *next_client;
2625 jack_event_t event;
2626 int upstream_is_jackd;
2628 jack_clear_fifos (engine);
2630 subgraph_client = 0;
2632 VERBOSE(engine, "++ jack_rechain_graph():");
2634 event.type = GraphReordered;
2636 for (n = 0, node = engine->clients, next = NULL; node; node = next) {
2638 next = jack_slist_next (node);
2640 VERBOSE(engine, "+++ client is now %s active ? %d",
2641 ((jack_client_internal_t *) node->data)->control->name,
2642 ((jack_client_internal_t *) node->data)->control->active);
2644 if (((jack_client_internal_t *) node->data)->control->active) {
2646 client = (jack_client_internal_t *) node->data;
2648 /* find the next active client. its ok for
2649 * this to be NULL */
2651 while (next) {
2652 if (((jack_client_internal_t *)
2653 next->data)->control->active) {
2654 break;
2656 next = jack_slist_next (next);
2659 if (next == NULL) {
2660 next_client = NULL;
2661 } else {
2662 next_client = (jack_client_internal_t *)
2663 next->data;
2666 client->execution_order = n;
2667 client->next_client = next_client;
2669 if (jack_client_is_internal (client)) {
2671 /* break the chain for the current
2672 * subgraph. the server will wait for
2673 * chain on the nth FIFO, and will
2674 * then execute this internal
2675 * client. */
2677 if (subgraph_client) {
2678 subgraph_client->subgraph_wait_fd =
2679 jack_get_fifo_fd (engine, n);
2680 VERBOSE (engine, "client %s: wait_fd="
2681 "%d, execution_order="
2682 "%lu.",
2683 subgraph_client->
2684 control->name,
2685 subgraph_client->
2686 subgraph_wait_fd, n);
2687 n++;
2690 VERBOSE (engine, "client %s: internal "
2691 "client, execution_order="
2692 "%lu.",
2693 client->control->name, n);
2695 /* this does the right thing for
2696 * internal clients too
2699 jack_deliver_event (engine, client, &event);
2701 subgraph_client = 0;
2703 } else {
2705 if (subgraph_client == NULL) {
2707 /* start a new subgraph. the
2708 * engine will start the chain
2709 * by writing to the nth
2710 * FIFO.
2713 subgraph_client = client;
2714 subgraph_client->subgraph_start_fd =
2715 jack_get_fifo_fd (engine, n);
2716 VERBOSE (engine, "client %s: "
2717 "start_fd=%d, execution"
2718 "_order=%lu.",
2719 subgraph_client->
2720 control->name,
2721 subgraph_client->
2722 subgraph_start_fd, n);
2724 /* this external client after
2725 this will have jackd as its
2726 upstream connection.
2729 upstream_is_jackd = 1;
2732 else {
2733 VERBOSE (engine, "client %s: in"
2734 " subgraph after %s, "
2735 "execution_order="
2736 "%lu.",
2737 client->control->name,
2738 subgraph_client->
2739 control->name, n);
2740 subgraph_client->subgraph_wait_fd = -1;
2742 /* this external client after
2743 this will have another
2744 client as its upstream
2745 connection.
2748 upstream_is_jackd = 0;
2751 /* make sure fifo for 'n + 1' exists
2752 * before issuing client reorder
2754 (void) jack_get_fifo_fd(
2755 engine, client->execution_order + 1);
2756 event.x.n = client->execution_order;
2757 event.y.n = upstream_is_jackd;
2758 jack_deliver_event (engine, client, &event);
2759 n++;
2764 if (subgraph_client) {
2765 subgraph_client->subgraph_wait_fd =
2766 jack_get_fifo_fd (engine, n);
2767 VERBOSE (engine, "client %s: wait_fd=%d, "
2768 "execution_order=%lu (last client).",
2769 subgraph_client->control->name,
2770 subgraph_client->subgraph_wait_fd, n);
2773 VERBOSE (engine, "-- jack_rechain_graph()");
2775 return err;
2778 static jack_nframes_t
2779 jack_get_port_total_latency (jack_engine_t *engine,
2780 jack_port_internal_t *port, int hop_count,
2781 int toward_port)
2783 JSList *node;
2784 jack_nframes_t latency;
2785 jack_nframes_t max_latency = 0;
2787 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2788 char prefix[32];
2789 int i;
2791 for (i = 0; i < hop_count; ++i) {
2792 prefix[i] = '\t';
2795 prefix[i] = '\0';
2796 #endif
2798 /* call tree must hold engine->client_lock. */
2800 latency = port->shared->latency;
2802 /* we don't prevent cyclic graphs, so we have to do something
2803 to bottom out in the event that they are created.
2806 if (hop_count > 8) {
2807 return latency;
2810 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2811 jack_info ("%sFor port %s (%s)", prefix, port->shared->name, (toward_port ? "toward" : "away"));
2812 #endif
2814 for (node = port->connections; node; node = jack_slist_next (node)) {
2816 jack_nframes_t this_latency;
2817 jack_connection_internal_t *connection;
2819 connection = (jack_connection_internal_t *) node->data;
2822 if ((toward_port &&
2823 (connection->source->shared == port->shared)) ||
2824 (!toward_port &&
2825 (connection->destination->shared == port->shared))) {
2827 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2828 jack_info ("%s\tskip connection %s->%s",
2829 prefix,
2830 connection->source->shared->name,
2831 connection->destination->shared->name);
2832 #endif
2834 continue;
2837 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2838 jack_info ("%s\tconnection %s->%s ... ",
2839 prefix,
2840 connection->source->shared->name,
2841 connection->destination->shared->name);
2842 #endif
2843 /* if we're a destination in the connection, recurse
2844 on the source to get its total latency
2847 if (connection->destination == port) {
2849 if (connection->source->shared->flags
2850 & JackPortIsTerminal) {
2851 this_latency = connection->source->
2852 shared->latency;
2853 } else {
2854 this_latency =
2855 jack_get_port_total_latency (
2856 engine, connection->source,
2857 hop_count + 1,
2858 toward_port);
2861 } else {
2863 /* "port" is the source, so get the latency of
2864 * the destination */
2865 if (connection->destination->shared->flags
2866 & JackPortIsTerminal) {
2867 this_latency = connection->destination->
2868 shared->latency;
2869 } else {
2870 this_latency =
2871 jack_get_port_total_latency (
2872 engine,
2873 connection->destination,
2874 hop_count + 1,
2875 toward_port);
2879 if (this_latency > max_latency) {
2880 max_latency = this_latency;
2884 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2885 jack_info ("%s\treturn %lu + %lu = %lu", prefix, latency, max_latency, latency + max_latency);
2886 #endif
2888 return latency + max_latency;
2891 static void
2892 jack_compute_port_total_latency (jack_engine_t* engine, jack_port_shared_t* port)
2894 if (port->in_use) {
2895 port->total_latency =
2896 jack_get_port_total_latency (
2897 engine, &engine->internal_ports[port->id],
2898 0, !(port->flags & JackPortIsOutput));
2902 static void
2903 jack_compute_all_port_total_latencies (jack_engine_t *engine)
2905 jack_port_shared_t *shared = engine->control->ports;
2906 unsigned int i;
2907 int toward_port;
2909 for (i = 0; i < engine->control->port_max; i++) {
2910 if (shared[i].in_use) {
2911 if (shared[i].flags & JackPortIsOutput) {
2912 toward_port = FALSE;
2913 } else {
2914 toward_port = TRUE;
2916 shared[i].total_latency =
2917 jack_get_port_total_latency (
2918 engine, &engine->internal_ports[i],
2919 0, toward_port);
2924 /* How the sort works:
2926 * Each client has a "sortfeeds" list of clients indicating which clients
2927 * it should be considered as feeding for the purposes of sorting the
2928 * graph. This list differs from the clients it /actually/ feeds in the
2929 * following ways:
2931 * 1. Connections from a client to itself are disregarded
2933 * 2. Connections to a driver client are disregarded
2935 * 3. If a connection from A to B is a feedback connection (ie there was
2936 * already a path from B to A when the connection was made) then instead
2937 * of B appearing on A's sortfeeds list, A will appear on B's sortfeeds
2938 * list.
2940 * If client A is on client B's sortfeeds list, client A must come after
2941 * client B in the execution order. The above 3 rules ensure that the
2942 * sortfeeds relation is always acyclic so that all ordering constraints
2943 * can actually be met.
2945 * Each client also has a "truefeeds" list which is the same as sortfeeds
2946 * except that feedback connections appear normally instead of reversed.
2947 * This is used to detect whether the graph has become acyclic.
2951 void
2952 jack_sort_graph (jack_engine_t *engine)
2954 /* called, obviously, must hold engine->client_lock */
2956 VERBOSE (engine, "++ jack_sort_graph");
2957 engine->clients = jack_slist_sort (engine->clients,
2958 (JCompareFunc) jack_client_sort);
2959 jack_compute_all_port_total_latencies (engine);
2960 jack_rechain_graph (engine);
2961 VERBOSE (engine, "-- jack_sort_graph");
2964 static int
2965 jack_client_sort (jack_client_internal_t *a, jack_client_internal_t *b)
2967 /* drivers are forced to the front, ie considered as sources
2968 rather than sinks for purposes of the sort */
2970 if (jack_client_feeds_transitive (a, b) ||
2971 (a->control->type == ClientDriver &&
2972 b->control->type != ClientDriver)) {
2973 return -1;
2974 } else if (jack_client_feeds_transitive (b, a) ||
2975 (b->control->type == ClientDriver &&
2976 a->control->type != ClientDriver)) {
2977 return 1;
2978 } else {
2979 return 0;
2983 /* transitive closure of the relation expressed by the sortfeeds lists. */
2984 static int
2985 jack_client_feeds_transitive (jack_client_internal_t *source,
2986 jack_client_internal_t *dest )
2988 jack_client_internal_t *med;
2989 JSList *node;
2991 if (jack_slist_find (source->sortfeeds, dest)) {
2992 return 1;
2995 for (node = source->sortfeeds; node; node = jack_slist_next (node)) {
2997 med = (jack_client_internal_t *) node->data;
2999 if (jack_client_feeds_transitive (med, dest)) {
3000 return 1;
3004 return 0;
3008 * Checks whether the graph has become acyclic and if so modifies client
3009 * sortfeeds lists to turn leftover feedback connections into normal ones.
3010 * This lowers latency, but at the expense of some data corruption.
3012 static void
3013 jack_check_acyclic (jack_engine_t *engine)
3015 JSList *srcnode, *dstnode, *portnode, *connnode;
3016 jack_client_internal_t *src, *dst;
3017 jack_port_internal_t *port;
3018 jack_connection_internal_t *conn;
3019 int stuck;
3020 int unsortedclients = 0;
3022 VERBOSE (engine, "checking for graph become acyclic");
3024 for (srcnode = engine->clients; srcnode;
3025 srcnode = jack_slist_next (srcnode)) {
3027 src = (jack_client_internal_t *) srcnode->data;
3028 src->tfedcount = src->fedcount;
3029 unsortedclients++;
3032 stuck = FALSE;
3034 /* find out whether a normal sort would have been possible */
3035 while (unsortedclients && !stuck) {
3037 stuck = TRUE;
3039 for (srcnode = engine->clients; srcnode;
3040 srcnode = jack_slist_next (srcnode)) {
3042 src = (jack_client_internal_t *) srcnode->data;
3044 if (!src->tfedcount) {
3046 stuck = FALSE;
3047 unsortedclients--;
3048 src->tfedcount = -1;
3050 for (dstnode = src->truefeeds; dstnode;
3051 dstnode = jack_slist_next (dstnode)) {
3053 dst = (jack_client_internal_t *)
3054 dstnode->data;
3055 dst->tfedcount--;
3061 if (stuck) {
3063 VERBOSE (engine, "graph is still cyclic" );
3064 } else {
3066 VERBOSE (engine, "graph has become acyclic");
3068 /* turn feedback connections around in sortfeeds */
3069 for (srcnode = engine->clients; srcnode;
3070 srcnode = jack_slist_next (srcnode)) {
3072 src = (jack_client_internal_t *) srcnode->data;
3074 for (portnode = src->ports; portnode;
3075 portnode = jack_slist_next (portnode)) {
3077 port = (jack_port_internal_t *) portnode->data;
3079 for (connnode = port->connections; connnode;
3080 connnode = jack_slist_next (connnode)) {
3082 conn = (jack_connection_internal_t*)
3083 connnode->data;
3085 if (conn->dir == -1 )
3087 /*&&
3088 conn->srcclient == src) */{
3090 VERBOSE (engine,
3091 "reversing connection from "
3092 "%s to %s",
3093 conn->srcclient->control->name,
3094 conn->dstclient->control->name);
3095 conn->dir = 1;
3096 conn->dstclient->sortfeeds =
3097 jack_slist_remove
3098 (conn->dstclient->sortfeeds,
3099 conn->srcclient);
3101 conn->srcclient->sortfeeds =
3102 jack_slist_prepend
3103 (conn->srcclient->sortfeeds,
3104 conn->dstclient );
3109 engine->feedbackcount = 0;
3114 * Dumps current engine configuration.
3116 void jack_dump_configuration(jack_engine_t *engine, int take_lock)
3118 JSList *clientnode, *portnode, *connectionnode;
3119 jack_client_internal_t *client;
3120 jack_client_control_t *ctl;
3121 jack_port_internal_t *port;
3122 jack_connection_internal_t* connection;
3123 int n, m, o;
3125 jack_info ("engine.c: <-- dump begins -->");
3127 if (take_lock) {
3128 jack_rdlock_graph (engine);
3131 for (n = 0, clientnode = engine->clients; clientnode;
3132 clientnode = jack_slist_next (clientnode)) {
3133 client = (jack_client_internal_t *) clientnode->data;
3134 ctl = client->control;
3136 jack_info ("client #%d: %s (type: %d, process? %s,"
3137 " start=%d wait=%d",
3138 ++n,
3139 ctl->name,
3140 ctl->type,
3141 ctl->process_cbset ? "yes" : "no",
3142 client->subgraph_start_fd,
3143 client->subgraph_wait_fd);
3145 for(m = 0, portnode = client->ports; portnode;
3146 portnode = jack_slist_next (portnode)) {
3147 port = (jack_port_internal_t *) portnode->data;
3149 jack_info("\t port #%d: %s", ++m,
3150 port->shared->name);
3152 for(o = 0, connectionnode = port->connections;
3153 connectionnode;
3154 connectionnode =
3155 jack_slist_next (connectionnode)) {
3156 connection = (jack_connection_internal_t *)
3157 connectionnode->data;
3159 jack_info("\t\t connection #%d: %s %s",
3160 ++o,
3161 (port->shared->flags
3162 & JackPortIsInput)? "<-": "->",
3163 (port->shared->flags & JackPortIsInput)?
3164 connection->source->shared->name:
3165 connection->destination->shared->name);
3170 if (take_lock) {
3171 jack_unlock_graph (engine);
3175 jack_info("engine.c: <-- dump ends -->");
3178 static int
3179 jack_port_do_connect (jack_engine_t *engine,
3180 const char *source_port,
3181 const char *destination_port)
3183 jack_connection_internal_t *connection;
3184 jack_port_internal_t *srcport, *dstport;
3185 jack_port_id_t src_id, dst_id;
3186 jack_client_internal_t *srcclient, *dstclient;
3187 JSList *it;
3189 if ((srcport = jack_get_port_by_name (engine, source_port)) == NULL) {
3190 jack_error ("unknown source port in attempted connection [%s]",
3191 source_port);
3192 return -1;
3195 if ((dstport = jack_get_port_by_name (engine, destination_port))
3196 == NULL) {
3197 jack_error ("unknown destination port in attempted connection"
3198 " [%s]", destination_port);
3199 return -1;
3202 if ((dstport->shared->flags & JackPortIsInput) == 0) {
3203 jack_error ("destination port in attempted connection of"
3204 " %s and %s is not an input port",
3205 source_port, destination_port);
3206 return -1;
3209 if ((srcport->shared->flags & JackPortIsOutput) == 0) {
3210 jack_error ("source port in attempted connection of %s and"
3211 " %s is not an output port",
3212 source_port, destination_port);
3213 return -1;
3216 if (srcport->shared->ptype_id != dstport->shared->ptype_id) {
3217 jack_error ("ports used in attemped connection are not of "
3218 "the same data type");
3219 return -1;
3222 if ((srcclient = jack_client_internal_by_id (engine,
3223 srcport->shared->client_id))
3224 == 0) {
3225 jack_error ("unknown client set as owner of port - "
3226 "cannot connect");
3227 return -1;
3230 if (!srcclient->control->active) {
3231 jack_error ("cannot connect ports owned by inactive clients;"
3232 " \"%s\" is not active", srcclient->control->name);
3233 return -1;
3236 if ((dstclient = jack_client_internal_by_id (engine,
3237 dstport->shared->client_id))
3238 == 0) {
3239 jack_error ("unknown client set as owner of port - cannot "
3240 "connect");
3241 return -1;
3244 if (!dstclient->control->active) {
3245 jack_error ("cannot connect ports owned by inactive clients;"
3246 " \"%s\" is not active", dstclient->control->name);
3247 return -1;
3250 for (it = srcport->connections; it; it = it->next) {
3251 if (((jack_connection_internal_t *)it->data)->destination
3252 == dstport) {
3253 return EEXIST;
3257 connection = (jack_connection_internal_t *)
3258 malloc (sizeof (jack_connection_internal_t));
3260 connection->source = srcport;
3261 connection->destination = dstport;
3262 connection->srcclient = srcclient;
3263 connection->dstclient = dstclient;
3265 src_id = srcport->shared->id;
3266 dst_id = dstport->shared->id;
3268 jack_lock_graph (engine);
3270 if (dstport->connections && !dstport->shared->has_mixdown) {
3271 jack_port_type_info_t *port_type =
3272 jack_port_type_info (engine, dstport);
3273 jack_error ("cannot make multiple connections to a port of"
3274 " type [%s]", port_type->type_name);
3275 free (connection);
3276 jack_unlock_graph (engine);
3277 return -1;
3278 } else {
3280 if (dstclient->control->type == ClientDriver)
3282 /* Ignore output connections to drivers for purposes
3283 of sorting. Drivers are executed first in the sort
3284 order anyway, and we don't want to treat graphs
3285 such as driver -> client -> driver as containing
3286 feedback */
3288 VERBOSE (engine,
3289 "connect %s and %s (output)",
3290 srcport->shared->name,
3291 dstport->shared->name);
3293 connection->dir = 1;
3296 else if (srcclient != dstclient) {
3298 srcclient->truefeeds = jack_slist_prepend
3299 (srcclient->truefeeds, dstclient);
3301 dstclient->fedcount++;
3303 if (jack_client_feeds_transitive (dstclient,
3304 srcclient ) ||
3305 (dstclient->control->type == ClientDriver &&
3306 srcclient->control->type != ClientDriver)) {
3308 /* dest is running before source so
3309 this is a feedback connection */
3311 VERBOSE (engine,
3312 "connect %s and %s (feedback)",
3313 srcport->shared->name,
3314 dstport->shared->name);
3316 dstclient->sortfeeds = jack_slist_prepend
3317 (dstclient->sortfeeds, srcclient);
3319 connection->dir = -1;
3320 engine->feedbackcount++;
3321 VERBOSE (engine,
3322 "feedback count up to %d",
3323 engine->feedbackcount);
3325 } else {
3327 /* this is not a feedback connection */
3329 VERBOSE (engine,
3330 "connect %s and %s (forward)",
3331 srcport->shared->name,
3332 dstport->shared->name);
3334 srcclient->sortfeeds = jack_slist_prepend
3335 (srcclient->sortfeeds, dstclient);
3337 connection->dir = 1;
3340 else
3342 /* this is a connection to self */
3344 VERBOSE (engine,
3345 "connect %s and %s (self)",
3346 srcport->shared->name,
3347 dstport->shared->name);
3349 connection->dir = 0;
3352 dstport->connections =
3353 jack_slist_prepend (dstport->connections, connection);
3354 srcport->connections =
3355 jack_slist_prepend (srcport->connections, connection);
3357 DEBUG ("actually sorted the graph...");
3359 jack_send_connection_notification (engine,
3360 srcport->shared->client_id,
3361 src_id, dst_id, TRUE);
3364 jack_send_connection_notification (engine,
3365 dstport->shared->client_id,
3366 dst_id, src_id, TRUE);
3368 /* send a port connection notification just once to everyone who cares excluding clients involved in the connection */
3370 jack_notify_all_port_interested_clients (engine, srcport->shared->client_id, dstport->shared->client_id, src_id, dst_id, 1);
3372 jack_sort_graph (engine);
3375 jack_unlock_graph (engine);
3377 return 0;
3381 jack_port_disconnect_internal (jack_engine_t *engine,
3382 jack_port_internal_t *srcport,
3383 jack_port_internal_t *dstport )
3386 JSList *node;
3387 jack_connection_internal_t *connect;
3388 int ret = -1;
3389 jack_port_id_t src_id, dst_id;
3390 int check_acyclic = engine->feedbackcount;
3392 /* call tree **** MUST HOLD **** engine->client_lock. */
3393 for (node = srcport->connections; node;
3394 node = jack_slist_next (node)) {
3396 connect = (jack_connection_internal_t *) node->data;
3398 if (connect->source == srcport &&
3399 connect->destination == dstport) {
3401 VERBOSE (engine, "DIS-connect %s and %s",
3402 srcport->shared->name,
3403 dstport->shared->name);
3405 srcport->connections =
3406 jack_slist_remove (srcport->connections,
3407 connect);
3408 dstport->connections =
3409 jack_slist_remove (dstport->connections,
3410 connect);
3412 src_id = srcport->shared->id;
3413 dst_id = dstport->shared->id;
3415 /* this is a bit harsh, but it basically says
3416 that if we actually do a disconnect, and
3417 its the last one, then make sure that any
3418 input monitoring is turned off on the
3419 srcport. this isn't ideal for all
3420 situations, but it works better for most of
3421 them.
3423 if (srcport->connections == NULL) {
3424 srcport->shared->monitor_requests = 0;
3427 jack_send_connection_notification (
3428 engine, srcport->shared->client_id, src_id,
3429 dst_id, FALSE);
3430 jack_send_connection_notification (
3431 engine, dstport->shared->client_id, dst_id,
3432 src_id, FALSE);
3434 /* send a port connection notification just once to everyone who cares excluding clients involved in the connection */
3436 jack_notify_all_port_interested_clients (engine, srcport->shared->client_id, dstport->shared->client_id, src_id, dst_id, 0);
3438 if (connect->dir) {
3440 jack_client_internal_t *src;
3441 jack_client_internal_t *dst;
3443 src = jack_client_internal_by_id
3444 (engine, srcport->shared->client_id);
3446 dst = jack_client_internal_by_id
3447 (engine, dstport->shared->client_id);
3449 src->truefeeds = jack_slist_remove
3450 (src->truefeeds, dst);
3452 dst->fedcount--;
3454 if (connect->dir == 1) {
3455 /* normal connection: remove dest from
3456 source's sortfeeds list */
3457 src->sortfeeds = jack_slist_remove
3458 (src->sortfeeds, dst);
3459 } else {
3460 /* feedback connection: remove source
3461 from dest's sortfeeds list */
3462 dst->sortfeeds = jack_slist_remove
3463 (dst->sortfeeds, src);
3464 engine->feedbackcount--;
3465 VERBOSE (engine,
3466 "feedback count down to %d",
3467 engine->feedbackcount);
3470 } /* else self-connection: do nothing */
3472 free (connect);
3473 ret = 0;
3474 break;
3478 if (check_acyclic) {
3479 jack_check_acyclic (engine);
3482 jack_sort_graph (engine);
3484 return ret;
3487 static int
3488 jack_port_do_disconnect_all (jack_engine_t *engine,
3489 jack_port_id_t port_id)
3491 if (port_id >= engine->control->port_max) {
3492 jack_error ("illegal port ID in attempted disconnection [%"
3493 PRIu32 "]", port_id);
3494 return -1;
3497 VERBOSE (engine, "clear connections for %s",
3498 engine->internal_ports[port_id].shared->name);
3500 jack_lock_graph (engine);
3501 jack_port_clear_connections (engine, &engine->internal_ports[port_id]);
3502 jack_sort_graph (engine);
3503 jack_unlock_graph (engine);
3505 return 0;
3508 static int
3509 jack_port_do_disconnect (jack_engine_t *engine,
3510 const char *source_port,
3511 const char *destination_port)
3513 jack_port_internal_t *srcport, *dstport;
3514 int ret = -1;
3516 if ((srcport = jack_get_port_by_name (engine, source_port)) == NULL) {
3517 jack_error ("unknown source port in attempted disconnection"
3518 " [%s]", source_port);
3519 return -1;
3522 if ((dstport = jack_get_port_by_name (engine, destination_port))
3523 == NULL) {
3524 jack_error ("unknown destination port in attempted"
3525 " disconnection [%s]", destination_port);
3526 return -1;
3529 jack_lock_graph (engine);
3531 ret = jack_port_disconnect_internal (engine, srcport, dstport);
3533 jack_unlock_graph (engine);
3535 return ret;
3538 int
3539 jack_get_fifo_fd (jack_engine_t *engine, unsigned int which_fifo)
3541 /* caller must hold client_lock */
3542 char path[PATH_MAX+1];
3543 struct stat statbuf;
3545 snprintf (path, sizeof (path), "%s-%d", engine->fifo_prefix,
3546 which_fifo);
3548 DEBUG ("%s", path);
3550 if (stat (path, &statbuf)) {
3551 if (errno == ENOENT) {
3553 if (mkfifo(path, 0666) < 0){
3554 jack_error ("cannot create inter-client FIFO"
3555 " [%s] (%s)\n", path,
3556 strerror (errno));
3557 return -1;
3560 } else {
3561 jack_error ("cannot check on FIFO %d\n", which_fifo);
3562 return -1;
3564 } else {
3565 if (!S_ISFIFO(statbuf.st_mode)) {
3566 jack_error ("FIFO %d (%s) already exists, but is not"
3567 " a FIFO!\n", which_fifo, path);
3568 return -1;
3572 if (which_fifo >= engine->fifo_size) {
3573 unsigned int i;
3575 engine->fifo = (int *)
3576 realloc (engine->fifo,
3577 sizeof (int) * (engine->fifo_size + 16));
3578 for (i = engine->fifo_size; i < engine->fifo_size + 16; i++) {
3579 engine->fifo[i] = -1;
3581 engine->fifo_size += 16;
3584 if (engine->fifo[which_fifo] < 0) {
3585 if ((engine->fifo[which_fifo] =
3586 open (path, O_RDWR|O_CREAT|O_NONBLOCK, 0666)) < 0) {
3587 jack_error ("cannot open fifo [%s] (%s)", path,
3588 strerror (errno));
3589 return -1;
3591 DEBUG ("opened engine->fifo[%d] == %d (%s)",
3592 which_fifo, engine->fifo[which_fifo], path);
3595 return engine->fifo[which_fifo];
3598 static void
3599 jack_clear_fifos (jack_engine_t *engine)
3601 /* caller must hold client_lock */
3603 unsigned int i;
3604 char buf[16];
3606 /* this just drains the existing FIFO's of any data left in
3607 them by aborted clients, etc. there is only ever going to
3608 be 0, 1 or 2 bytes in them, but we'll allow for up to 16.
3610 for (i = 0; i < engine->fifo_size; i++) {
3611 if (engine->fifo[i] >= 0) {
3612 int nread = read (engine->fifo[i], buf, sizeof (buf));
3614 if (nread < 0 && errno != EAGAIN) {
3615 jack_error ("clear fifo[%d] error: %s",
3616 i, strerror (errno));
3622 static int
3623 jack_use_driver (jack_engine_t *engine, jack_driver_t *driver)
3625 if (engine->driver) {
3626 engine->driver->detach (engine->driver, engine);
3627 engine->driver = 0;
3630 if (driver) {
3631 engine->driver = driver;
3633 if (driver->attach (driver, engine)) {
3634 engine->driver = 0;
3635 return -1;
3638 engine->rolling_interval =
3639 jack_rolling_interval (driver->period_usecs);
3642 return 0;
3646 /* PORT RELATED FUNCTIONS */
3649 static jack_port_id_t
3650 jack_get_free_port (jack_engine_t *engine)
3653 jack_port_id_t i;
3655 pthread_mutex_lock (&engine->port_lock);
3657 for (i = 0; i < engine->port_max; i++) {
3658 if (engine->control->ports[i].in_use == 0) {
3659 engine->control->ports[i].in_use = 1;
3660 break;
3664 pthread_mutex_unlock (&engine->port_lock);
3666 if (i == engine->port_max) {
3667 return (jack_port_id_t) -1;
3670 return i;
3673 void
3674 jack_port_release (jack_engine_t *engine, jack_port_internal_t *port)
3676 pthread_mutex_lock (&engine->port_lock);
3677 port->shared->in_use = 0;
3678 port->shared->alias1[0] = '\0';
3679 port->shared->alias2[0] = '\0';
3681 if (port->buffer_info) {
3682 jack_port_buffer_list_t *blist =
3683 jack_port_buffer_list (engine, port);
3684 pthread_mutex_lock (&blist->lock);
3685 blist->freelist =
3686 jack_slist_prepend (blist->freelist,
3687 port->buffer_info);
3688 port->buffer_info = NULL;
3689 pthread_mutex_unlock (&blist->lock);
3691 pthread_mutex_unlock (&engine->port_lock);
3694 jack_port_internal_t *
3695 jack_get_port_internal_by_name (jack_engine_t *engine, const char *name)
3697 jack_port_id_t id;
3699 pthread_mutex_lock (&engine->port_lock);
3701 for (id = 0; id < engine->port_max; id++) {
3702 if (jack_port_name_equals (&engine->control->ports[id], name)) {
3703 break;
3707 pthread_mutex_unlock (&engine->port_lock);
3709 if (id != engine->port_max) {
3710 return &engine->internal_ports[id];
3711 } else {
3712 return NULL;
3717 jack_port_do_register (jack_engine_t *engine, jack_request_t *req, int internal)
3719 jack_port_id_t port_id;
3720 jack_port_shared_t *shared;
3721 jack_port_internal_t *port;
3722 jack_client_internal_t *client;
3723 unsigned long i;
3724 char *backend_client_name;
3725 size_t len;
3727 for (i = 0; i < engine->control->n_port_types; ++i) {
3728 if (strcmp (req->x.port_info.type,
3729 engine->control->port_types[i].type_name) == 0) {
3730 break;
3734 if (i == engine->control->n_port_types) {
3735 jack_error ("cannot register a port of type \"%s\"",
3736 req->x.port_info.type);
3737 return -1;
3740 jack_lock_graph (engine);
3741 if ((client = jack_client_internal_by_id (engine,
3742 req->x.port_info.client_id))
3743 == NULL) {
3744 jack_error ("unknown client id in port registration request");
3745 jack_unlock_graph (engine);
3746 return -1;
3749 if ((port = jack_get_port_by_name(engine, req->x.port_info.name)) != NULL) {
3750 jack_error ("duplicate port name in port registration request");
3751 jack_unlock_graph (engine);
3752 return -1;
3755 if ((port_id = jack_get_free_port (engine)) == (jack_port_id_t) -1) {
3756 jack_error ("no ports available!");
3757 jack_unlock_graph (engine);
3758 return -1;
3761 shared = &engine->control->ports[port_id];
3763 if (!internal || !engine->driver)
3764 goto fallback;
3766 backend_client_name = (char *) engine->driver->internal_client->control->name;
3767 len = strlen (backend_client_name);
3769 if (strncmp (req->x.port_info.name, backend_client_name, len) != 0)
3770 goto fallback;
3772 /* use backend's original as an alias, use predefined names */
3774 if (strcmp(req->x.port_info.type, JACK_DEFAULT_AUDIO_TYPE) == 0) {
3775 if ((req->x.port_info.flags & (JackPortIsPhysical|JackPortIsInput)) == (JackPortIsPhysical|JackPortIsInput)) {
3776 snprintf (shared->name, sizeof (shared->name), JACK_BACKEND_ALIAS ":playback_%d", ++engine->audio_out_cnt);
3777 strcpy (shared->alias1, req->x.port_info.name);
3778 goto next;
3780 else if ((req->x.port_info.flags & (JackPortIsPhysical|JackPortIsOutput)) == (JackPortIsPhysical|JackPortIsOutput)) {
3781 snprintf (shared->name, sizeof (shared->name), JACK_BACKEND_ALIAS ":capture_%d", ++engine->audio_in_cnt);
3782 strcpy (shared->alias1, req->x.port_info.name);
3783 goto next;
3786 else if (strcmp(req->x.port_info.type, JACK_DEFAULT_MIDI_TYPE) == 0) {
3787 if ((req->x.port_info.flags & (JackPortIsPhysical|JackPortIsInput)) == (JackPortIsPhysical|JackPortIsInput)) {
3788 snprintf (shared->name, sizeof (shared->name), JACK_BACKEND_ALIAS ":midi_playback_%d", ++engine->midi_out_cnt);
3789 strcpy (shared->alias1, req->x.port_info.name);
3790 goto next;
3792 else if ((req->x.port_info.flags & (JackPortIsPhysical|JackPortIsOutput)) == (JackPortIsPhysical|JackPortIsOutput)) {
3793 snprintf (shared->name, sizeof (shared->name), JACK_BACKEND_ALIAS ":midi_capture_%d", ++engine->midi_in_cnt);
3794 strcpy (shared->alias1, req->x.port_info.name);
3795 goto next;
3799 fallback:
3800 strcpy (shared->name, req->x.port_info.name);
3802 next:
3803 shared->ptype_id = engine->control->port_types[i].ptype_id;
3804 shared->client_id = req->x.port_info.client_id;
3805 shared->flags = req->x.port_info.flags;
3806 shared->latency = 0;
3807 shared->monitor_requests = 0;
3809 port = &engine->internal_ports[port_id];
3811 port->shared = shared;
3812 port->connections = 0;
3813 port->buffer_info = NULL;
3815 if (jack_port_assign_buffer (engine, port)) {
3816 jack_error ("cannot assign buffer for port");
3817 jack_port_release (engine, &engine->internal_ports[port_id]);
3818 jack_unlock_graph (engine);
3819 return -1;
3822 client->ports = jack_slist_prepend (client->ports, port);
3823 jack_port_registration_notify (engine, port_id, TRUE);
3824 jack_unlock_graph (engine);
3826 VERBOSE (engine, "registered port %s, offset = %u",
3827 shared->name, (unsigned int)shared->offset);
3829 req->x.port_info.port_id = port_id;
3831 return 0;
3835 jack_port_do_unregister (jack_engine_t *engine, jack_request_t *req)
3837 jack_client_internal_t *client;
3838 jack_port_shared_t *shared;
3839 jack_port_internal_t *port;
3841 if (req->x.port_info.port_id < 0 ||
3842 req->x.port_info.port_id > engine->port_max) {
3843 jack_error ("invalid port ID %" PRIu32
3844 " in unregister request",
3845 req->x.port_info.port_id);
3846 return -1;
3849 shared = &engine->control->ports[req->x.port_info.port_id];
3851 if (shared->client_id != req->x.port_info.client_id) {
3852 jack_error ("Client %" PRIu32
3853 " is not allowed to remove port %s",
3854 req->x.port_info.client_id, shared->name);
3855 return -1;
3858 jack_lock_graph (engine);
3859 if ((client = jack_client_internal_by_id (engine, shared->client_id))
3860 == NULL) {
3861 jack_error ("unknown client id in port registration request");
3862 jack_unlock_graph (engine);
3863 return -1;
3866 port = &engine->internal_ports[req->x.port_info.port_id];
3868 jack_port_clear_connections (engine, port);
3869 jack_port_release (engine,
3870 &engine->internal_ports[req->x.port_info.port_id]);
3872 client->ports = jack_slist_remove (client->ports, port);
3873 jack_port_registration_notify (engine, req->x.port_info.port_id,
3874 FALSE);
3875 jack_unlock_graph (engine);
3877 return 0;
3881 jack_do_get_port_connections (jack_engine_t *engine, jack_request_t *req,
3882 int reply_fd)
3884 jack_port_internal_t *port;
3885 JSList *node;
3886 unsigned int i;
3887 int ret = -1;
3888 int internal = FALSE;
3890 jack_rdlock_graph (engine);
3892 port = &engine->internal_ports[req->x.port_info.port_id];
3894 DEBUG ("Getting connections for port '%s'.", port->shared->name);
3896 req->x.port_connections.nports = jack_slist_length (port->connections);
3897 req->status = 0;
3899 /* figure out if this is an internal or external client */
3901 for (node = engine->clients; node; node = jack_slist_next (node)) {
3903 if (((jack_client_internal_t *) node->data)->request_fd
3904 == reply_fd) {
3905 internal = jack_client_is_internal(
3906 (jack_client_internal_t *) node->data);
3907 break;
3911 if (!internal) {
3912 if (write (reply_fd, req, sizeof (*req))
3913 < (ssize_t) sizeof (req)) {
3914 jack_error ("cannot write GetPortConnections result "
3915 "to client via fd = %d (%s)",
3916 reply_fd, strerror (errno));
3917 goto out;
3919 } else {
3920 req->x.port_connections.ports = (const char **)
3921 malloc (sizeof (char *)
3922 * req->x.port_connections.nports);
3925 if (req->type == GetPortConnections) {
3927 for (i = 0, node = port->connections; node;
3928 node = jack_slist_next (node), ++i) {
3930 jack_port_id_t port_id;
3932 if (((jack_connection_internal_t *) node->data)->source
3933 == port) {
3934 port_id = ((jack_connection_internal_t *)
3935 node->data)->destination->shared->id;
3936 } else {
3937 port_id = ((jack_connection_internal_t *)
3938 node->data)->source->shared->id;
3941 if (internal) {
3943 /* internal client asking for
3944 * names. store in malloc'ed space,
3945 * client frees
3947 char **ports = req->x.port_connections.ports;
3949 ports[i] =
3950 engine->control->ports[port_id].name;
3952 } else {
3954 /* external client asking for
3955 * names. we write the port id's to
3956 * the reply fd.
3958 if (write (reply_fd, &port_id,
3959 sizeof (port_id))
3960 < (ssize_t) sizeof (port_id)) {
3961 jack_error ("cannot write port id "
3962 "to client");
3963 goto out;
3969 ret = 0;
3971 out:
3972 req->status = ret;
3973 jack_unlock_graph (engine);
3974 return ret;
3977 void
3978 jack_port_registration_notify (jack_engine_t *engine,
3979 jack_port_id_t port_id, int yn)
3981 jack_event_t event;
3982 jack_client_internal_t *client;
3983 JSList *node;
3985 event.type = (yn ? PortRegistered : PortUnregistered);
3986 event.x.port_id = port_id;
3988 for (node = engine->clients; node; node = jack_slist_next (node)) {
3990 client = (jack_client_internal_t *) node->data;
3992 if (!client->control->active) {
3993 continue;
3996 if (client->control->port_register_cbset) {
3997 if (jack_deliver_event (engine, client, &event)) {
3998 jack_error ("cannot send port registration"
3999 " notification to %s (%s)",
4000 client->control->name,
4001 strerror (errno));
4007 void
4008 jack_client_registration_notify (jack_engine_t *engine,
4009 const char* name, int yn)
4011 jack_event_t event;
4012 jack_client_internal_t *client;
4013 JSList *node;
4015 event.type = (yn ? ClientRegistered : ClientUnregistered);
4016 snprintf (event.x.name, sizeof (event.x.name), "%s", name);
4018 for (node = engine->clients; node; node = jack_slist_next (node)) {
4020 client = (jack_client_internal_t *) node->data;
4022 if (!client->control->active) {
4023 continue;
4026 if (strcmp ((char*) client->control->name, (char*) name) == 0) {
4027 /* do not notify client of its own registration */
4028 continue;
4031 if (client->control->client_register_cbset) {
4032 if (jack_deliver_event (engine, client, &event)) {
4033 jack_error ("cannot send client registration"
4034 " notification to %s (%s)",
4035 client->control->name,
4036 strerror (errno));
4043 jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
4045 jack_port_buffer_list_t *blist =
4046 jack_port_buffer_list (engine, port);
4047 jack_port_buffer_info_t *bi;
4049 if (port->shared->flags & JackPortIsInput) {
4050 port->shared->offset = 0;
4051 return 0;
4054 pthread_mutex_lock (&blist->lock);
4056 if (blist->freelist == NULL) {
4057 jack_port_type_info_t *port_type =
4058 jack_port_type_info (engine, port);
4059 jack_error ("all %s port buffers in use!",
4060 port_type->type_name);
4061 pthread_mutex_unlock (&blist->lock);
4062 return -1;
4065 bi = (jack_port_buffer_info_t *) blist->freelist->data;
4066 blist->freelist = jack_slist_remove (blist->freelist, bi);
4068 port->shared->offset = bi->offset;
4069 port->buffer_info = bi;
4071 pthread_mutex_unlock (&blist->lock);
4072 return 0;
4075 static jack_port_internal_t *
4076 jack_get_port_by_name (jack_engine_t *engine, const char *name)
4078 jack_port_id_t id;
4080 /* Note the potential race on "in_use". Other design
4081 elements prevent this from being a problem.
4084 for (id = 0; id < engine->port_max; id++) {
4085 if (engine->control->ports[id].in_use &&
4086 jack_port_name_equals (&engine->control->ports[id], name)) {
4087 return &engine->internal_ports[id];
4091 return NULL;
4094 static int
4095 jack_send_connection_notification (jack_engine_t *engine,
4096 jack_client_id_t client_id,
4097 jack_port_id_t self_id,
4098 jack_port_id_t other_id, int connected)
4101 jack_client_internal_t *client;
4102 jack_event_t event;
4104 if ((client = jack_client_internal_by_id (engine, client_id)) == NULL) {
4105 jack_error ("no such client %" PRIu32
4106 " during connection notification", client_id);
4107 return -1;
4110 if (client->control->active) {
4111 event.type = (connected ? PortConnected : PortDisconnected);
4112 event.x.self_id = self_id;
4113 event.y.other_id = other_id;
4115 if (jack_deliver_event (engine, client, &event)) {
4116 jack_error ("cannot send port connection notification"
4117 " to client %s (%s)",
4118 client->control->name, strerror (errno));
4119 return -1;
4123 return 0;