1 /* -*- mode: c; c-file-style: "bsd"; -*- */
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.
26 #include <sys/socket.h>
38 #include <sys/types.h>
42 #include <jack/internal.h>
43 #include <jack/engine.h>
44 #include <jack/messagebuffer.h>
45 #include <jack/driver.h>
47 #include <jack/thread.h>
48 #include <sysdeps/poll.h>
49 #include <sysdeps/ipc.h>
53 #endif /* USE_MLOCK */
55 #ifdef USE_CAPABILITIES
56 /* capgetp and capsetp are linux only extensions, not posix */
58 #include <sys/capability.h>
61 #include "clientengine.h"
62 #include "transengine.h"
64 #include "libjack/local.h"
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
*);
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
*,
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
,
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
*,
108 jack_port_id_t
, int);
109 static int jack_deliver_event (jack_engine_t
*, jack_client_internal_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
,
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
*);
138 jack_rolling_interval (jack_time_t period_usecs
)
140 return floor ((JACK_ENGINE_ROLLING_INTERVAL
* 1000.0f
) / period_usecs
);
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
);
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
];
178 make_directory (const char *path
)
182 if (stat (path
, &statbuf
)) {
184 if (errno
== ENOENT
) {
187 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
193 if (mkdir (path
, mode
) < 0){
194 jack_error ("cannot create %s directory (%s)\n",
195 path
, strerror (errno
));
199 jack_error ("cannot stat() %s\n", path
);
205 if (!S_ISDIR (statbuf
.st_mode
)) {
206 jack_error ("%s already exists, but is not"
207 " a directory!\n", path
);
216 make_socket_subdirectories (const char *server_name
)
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
));
227 if (!S_ISDIR(statbuf
.st_mode
)) {
228 jack_error ("%s exists, but is not a directory!\n",
234 /* create user subdirectory */
235 if (make_directory (jack_user_dir ()) < 0) {
239 /* create server_name subdirectory */
240 if (make_directory (jack_server_dir (server_name
, server_dir
)) < 0) {
248 make_sockets (const char *server_name
, int fd
[2])
250 struct sockaddr_un addr
;
252 char server_dir
[PATH_MAX
+1] = "";
254 if (make_socket_subdirectories (server_name
) < 0) {
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)",
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) {
276 jack_error ("all possible server socket names in use!!!");
281 if (bind (fd
[0], (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
282 jack_error ("cannot bind server to socket (%s)",
288 if (listen (fd
[0], 1) < 0) {
289 jack_error ("cannot enable listen on server socket (%s)",
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)",
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) {
314 jack_error ("all possible server ACK socket names in use!!!");
320 if (bind (fd
[1], (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
321 jack_error ("cannot bind server to socket (%s)",
328 if (listen (fd
[1], 1) < 0) {
329 jack_error ("cannot enable listen on server socket (%s)",
340 jack_engine_place_port_buffers (jack_engine_t
* engine
,
341 jack_port_type_id_t ptid
,
342 jack_shmsize_t one_buffer
,
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
);
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
365 while (offset
< size
) {
367 offset
+= one_buffer
;
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
];
375 (port
->flags
& JackPortIsOutput
) &&
376 port
->ptype_id
== ptid
) {
377 bi
= engine
->internal_ports
[i
].buffer_info
;
379 port
->offset
= bi
->offset
;
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
392 bi
= pti
->info
= (jack_port_buffer_info_t
*)
393 malloc (nports
* sizeof (jack_port_buffer_info_t
));
395 while (offset
< size
) {
397 pti
->freelist
= jack_slist_append (pti
->freelist
, bi
);
398 offset
+= one_buffer
;
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
,
409 port_type
->zero_buffer_offset
= bi
->offset
;
410 if (ptid
== JACK_AUDIO_PORT_TYPE
)
411 engine
->silent_buffer
= bi
;
413 /* initialize buffers */
416 jack_shm_info_t
*shm_info
= &engine
->port_segment
[ptid
];
417 char* shm_segment
= (char *) jack_shm_addr(shm_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...
429 jack_resize_port_segment (jack_engine_t
*engine
,
430 jack_port_type_id_t ptid
,
431 unsigned long nports
)
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
;
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"
459 if (jack_attach_shm (shm_info
)) {
460 jack_error ("cannot attach to new port segment "
461 "(%s)", strerror (errno
));
465 engine
->control
->port_types
[ptid
].shm_registry_index
=
470 /* resize existing buffer segment */
471 if (jack_resize_shm (shm_info
, size
)) {
472 jack_error ("cannot resize port segment to %d bytes,"
479 jack_engine_place_port_buffers (engine
, ptid
, one_buffer
, size
, nports
, engine
->control
->buffer_size
);
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
493 int rc
= mlock (jack_shm_addr (shm_info
), size
);
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
;
504 jack_deliver_event_to_all (engine
, &event
);
507 /* The driver invokes this callback both initially and whenever its
508 * buffer size changes.
511 jack_driver_buffer_size (jack_engine_t
*engine
, jack_nframes_t nframes
)
517 VERBOSE (engine
, "new buffer size %" PRIu32
, nframes
);
519 engine
->control
->buffer_size
= nframes
;
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
);
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 */
548 jack_driver_t
* driver
= engine
->driver
;
551 return ENXIO
; /* no such device */
553 if (!jack_power_of_two(nframes
)) {
554 jack_error("buffer size %" PRIu32
" not a power of 2",
559 rc
= driver
->bufsize(driver
, nframes
);
561 jack_error("driver does not support %" PRIu32
562 "-frame buffers", nframes
);
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 */
603 return jack_slist_next (node
);
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;
616 static const int system_clock_monotonic
= 0;
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 */
642 #ifdef JACK_USE_MACH_THREADS
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 */
667 jack_process_external(jack_engine_t
*engine
, JSList
*node
)
671 struct pollfd pfd
[1];
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
;
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)",
698 engine
->process_errors
++;
699 jack_lock_problems (engine
);
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 */
710 poll_timeout_usecs
= (engine
->client_timeout_msecs
> 0 ?
711 engine
->client_timeout_msecs
* 1000 :
712 engine
->driver
->period_usecs
);
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)",
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
);
737 if (pfd
[0].revents
& POLLIN
) {
741 } else if (status
== 0) {
743 /* no events, no errors, we woke up because poll()
744 decided that time was up ...
748 if (linux_poll_bug_encountered (engine
, then
, &poll_timeout_usecs
)) {
752 if (poll_timeout_usecs
< 200) {
753 VERBOSE (engine
, "FALSE WAKEUP skipped, remaining = %lld usec", poll_timeout_usecs
);
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
);
769 now
= jack_get_microseconds ();
772 VERBOSE (engine
, "at %" PRIu64
773 " waiting on %d for %" PRIu64
774 " usecs, status = %d sig = %" PRIu64
775 " awa = %" PRIu64
" fin = %" PRIu64
778 client
->subgraph_wait_fd
,
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 */
794 DEBUG ("reading byte from subgraph_wait_fd==%d",
795 client
->subgraph_wait_fd
);
797 if (read (client
->subgraph_wait_fd
, &c
, sizeof(c
))
799 jack_error ("pp: cannot clean up byte from graph wait "
800 "fd (%s)", strerror (errno
));
802 return NULL
; /* will stop the loop */
806 /* Move to next internal client (or end of client list) */
808 if (jack_client_is_internal ((jack_client_internal_t
*)
812 node
= jack_slist_next (node
);
818 #endif /* JACK_USE_MACH_THREADS */
821 jack_engine_process (jack_engine_t
*engine
, jack_nframes_t nframes
)
823 /* precondition: caller has graph_lock */
824 jack_client_internal_t
*client
;
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
;
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
);
852 node
= jack_process_external (engine
, node
);
856 return engine
->process_errors
> 0;
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
;
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
;
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
);
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
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.
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;
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
);
965 engine
->watchdog_check
= 0;
970 jack_start_watchdog (jack_engine_t
*engine
)
972 int watchdog_priority
= engine
->rtpriority
+ 10;
974 int max_priority
= sched_get_priority_max (SCHED_FIFO
);
976 int max_priority
= -1;
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");
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
)
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
,
1009 jack_error ("bizarre error loading driver shared "
1010 "object %s", driver_desc
->file
);
1015 info
->initialize
= dlsym (info
->handle
, "driver_initialize");
1017 if ((errstr
= dlerror ()) != 0) {
1018 jack_error ("no initialize function in shared object %s\n",
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",
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",
1043 dlclose (info
->handle
);
1051 jack_driver_unload (jack_driver_t
*driver
)
1053 void* handle
= driver
->handle
;
1054 driver
->finish (driver
);
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
) {
1071 if ((client
= jack_create_driver_client (engine
, info
->client_name
)
1076 if ((driver
= info
->initialize (client
->private_client
,
1077 driver_params
)) == NULL
) {
1082 driver
->handle
= info
->handle
;
1083 driver
->finish
= info
->finish
;
1084 driver
->internal_client
= client
;
1087 if (jack_use_driver (engine
, driver
) < 0) {
1088 jack_client_delete (engine
, client
);
1092 engine
->driver_desc
= driver_desc
;
1093 engine
->driver_params
= driver_params
;
1095 if (engine
->control
->real_time
) {
1096 if (jack_start_watchdog (engine
)) {
1099 engine
->watchdog_check
= 1;
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
;
1111 int have_all_caps
= 1;
1114 VERBOSE (engine
, "check: could not allocate capability"
1115 " working storage");
1120 if (capgetp (pid
, caps
)) {
1121 VERBOSE (engine
, "check: could not get capabilities "
1122 "for process %d", pid
);
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
) {
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
) {
1137 cap_get_flag(caps
, CAP_SYS_RESOURCE
, CAP_EFFECTIVE
, &cap
);
1138 if (cap
== CAP_CLEAR
) {
1142 cap_get_flag(caps
, CAP_IPC_LOCK
, CAP_EFFECTIVE
, &cap
);
1143 if (cap
== CAP_CLEAR
) {
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
};
1160 VERBOSE (engine
, "give: could not allocate capability"
1161 " working storage");
1165 if (capgetp (pid
, caps
)) {
1166 VERBOSE (engine
, "give: could not get current "
1167 "capabilities for process %d", pid
);
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
)) {
1182 jack_set_client_capabilities (jack_engine_t
*engine
, pid_t cap_pid
)
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 "
1197 VERBOSE (engine
, "gave capabilities to"
1205 #endif /* USE_CAPABILITIES */
1207 /* perform internal or external client request
1209 * reply_fd is NULL for internal requests
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"
1218 pthread_mutex_lock (&engine
->request_lock
);
1220 DEBUG ("got a request of type %d", req
->type
);
1222 switch (req
->type
) {
1224 req
->status
= jack_port_do_register (engine
, req
, reply_fd
? FALSE
: TRUE
);
1227 case UnRegisterPort
:
1228 req
->status
= jack_port_do_unregister (engine
, req
);
1232 req
->status
= jack_port_do_connect
1233 (engine
, req
->x
.connect
.source_port
,
1234 req
->x
.connect
.destination_port
);
1237 case DisconnectPort
:
1238 req
->status
= jack_port_do_disconnect_all
1239 (engine
, req
->x
.port_info
.port_id
);
1242 case DisconnectPorts
:
1243 req
->status
= jack_port_do_disconnect
1244 (engine
, req
->x
.connect
.source_port
,
1245 req
->x
.connect
.destination_port
);
1248 case ActivateClient
:
1249 req
->status
= jack_client_activate (engine
, req
->x
.client_id
);
1252 case DeactivateClient
:
1253 req
->status
= jack_client_deactivate (engine
, req
->x
.client_id
);
1256 case SetTimeBaseClient
:
1257 req
->status
= jack_timebase_set (engine
,
1258 req
->x
.timebase
.client_id
,
1259 req
->x
.timebase
.conditional
);
1262 case ResetTimeBaseClient
:
1263 req
->status
= jack_timebase_reset (engine
, req
->x
.client_id
);
1268 jack_transport_client_set_sync (engine
,
1272 case ResetSyncClient
:
1274 jack_transport_client_reset_sync (engine
,
1278 case SetSyncTimeout
:
1279 req
->status
= jack_transport_set_sync_timeout (engine
,
1283 #ifdef USE_CAPABILITIES
1284 case SetClientCapabilities
:
1285 req
->status
= jack_set_client_capabilities (engine
,
1288 #endif /* USE_CAPABILITIES */
1290 case GetPortConnections
:
1291 case GetPortNConnections
:
1292 //JOQ bug: reply_fd may be NULL if internal request
1294 jack_do_get_port_connections (engine
, req
, *reply_fd
))
1296 /* we have already replied, don't do it again */
1302 req
->status
= jack_start_freewheeling (engine
);
1306 req
->status
= jack_stop_freewheeling (engine
);
1310 req
->status
= jack_set_buffer_size_request (engine
,
1314 case IntClientHandle
:
1315 jack_intclient_handle_request (engine
, req
);
1319 jack_intclient_load_request (engine
, req
);
1323 jack_intclient_name_request (engine
, req
);
1326 case IntClientUnload
:
1327 jack_intclient_unload_request (engine
, req
);
1330 case RecomputeTotalLatencies
:
1331 jack_lock_graph (engine
);
1332 jack_compute_all_port_total_latencies (engine
);
1333 jack_unlock_graph (engine
);
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
);
1345 /* some requests are handled entirely on the client
1346 * side, by adjusting the shared memory area(s) */
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
;
1363 handle_external_client_request (jack_engine_t
*engine
, int fd
)
1365 /* CALLER holds read lock on graph */
1368 jack_client_internal_t
*client
= 0;
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
;
1380 if (client
== NULL
) {
1381 jack_error ("client input on unknown fd %d!", fd
);
1385 if ((r
= read (client
->request_fd
, &req
, sizeof (req
)))
1386 < (ssize_t
) sizeof (req
)) {
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 */
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 ?
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");
1426 DEBUG ("*not* replying to client");
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");
1444 if ((client
= jack_client_internal_by_id (engine
, req
.client_id
))
1446 jack_error ("unknown client ID in ACK connection request");
1450 client
->event_fd
= client_fd
;
1451 VERBOSE (engine
, "new client %s using %d for events", client
->control
->name
,
1456 if (write (client
->event_fd
, &res
, sizeof (res
)) != sizeof (res
)) {
1457 jack_error ("cannot write ACK connection response to client");
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;
1476 const int fixed_fd_cnt
= 3;
1482 jack_rdlock_graph (engine
);
1484 clients
= jack_slist_length (engine
->clients
);
1486 if (engine
->pfd_size
< fixed_fd_cnt
+ clients
) {
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
) {
1508 engine
->pfd
[engine
->pfd_max
].fd
= client
->request_fd
;
1509 engine
->pfd
[engine
->pfd_max
].events
= POLLIN
|POLLPRI
|POLLERR
|POLLHUP
|POLLNVAL
;
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
) {
1525 jack_error ("poll failed (%s)", strerror (errno
));
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
) {
1543 if (engine
->pfd
[2].revents
& POLLIN
) {
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) {
1558 if (engine
->pfd
[i
].revents
& ~POLLIN
) {
1560 jack_mark_client_socket_error (engine
, engine
->pfd
[i
].fd
);
1561 jack_lock_problems (engine
);
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"
1570 jack_lock_problems (engine
);
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");
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)",
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");
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
);
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
;
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
1673 if (jack_acquire_real_time_scheduling (pthread_self(), 10) != 0) {
1674 /* can't run realtime - time to bomb */
1678 jack_drop_real_time_scheduling (pthread_self());
1682 if (do_mlock
&& (mlockall (MCL_CURRENT
| MCL_FUTURE
) != 0)) {
1683 jack_error ("cannot lock down memory for jackd (%s)",
1687 #endif /* ENSURE_MLOCK */
1689 #endif /* USE_MLOCK */
1692 /* start a thread to display messages from realtime threads */
1693 jack_messagebuffer_init();
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;
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
));
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
));
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
));
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
));
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
);
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");
1844 engine
->control
->port_max
= engine
->port_max
;
1845 engine
->control
->real_time
= realtime
;
1846 engine
->control
->client_priority
= (realtime
1847 ? engine
->rtpriority
- 1
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
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");
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",
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 "
1901 if (engine
->verbose
) {
1903 cap_t cap
= cap_init();
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
);
1926 jack_engine_delay (jack_engine_t
*engine
, float delayed_usecs
)
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
;
1939 jack_deliver_event_to_all (engine
, &event
);
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
1949 // really need a memory barrier here
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
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
);
1990 jack_unlock_graph (engine
);
1993 VERBOSE (engine
, "freewheel came to an end, naturally");
1998 jack_start_freewheeling (jack_engine_t
* engine
)
2002 if (engine
->freewheeling
) {
2006 if (engine
->driver
== NULL
) {
2007 jack_error ("cannot start freewheeling without a driver!");
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");
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");
2035 jack_stop_freewheeling (jack_engine_t
* engine
)
2040 if (!engine
->freewheeling
) {
2044 if (engine
->driver
== NULL
) {
2045 jack_error ("cannot start freewheeling without a driver!");
2049 if (!engine
->freewheeling
) {
2050 VERBOSE (engine
, "stop freewheel when not freewheeling");
2054 /* tell the freewheel thread to stop, and wait for it
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");
2078 jack_run_one_cycle (jack_engine_t
*engine
, jack_nframes_t nframes
,
2079 float delayed_usecs
)
2081 jack_driver_t
* driver
= engine
->driver
;
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
);
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
);
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
);
2125 if (!engine
->freewheeling
) {
2126 DEBUG("waiting for driver read\n");
2127 if (driver
->read (driver
, nframes
)) {
2132 DEBUG("run process\n");
2134 if (jack_engine_process (engine
, nframes
) == 0) {
2135 if (!engine
->freewheeling
) {
2136 if (driver
->write (driver
, nframes
)) {
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
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)) {
2159 "client %s has died/exited",
2160 client
->control
->name
);
2163 if(client
->control
->last_status
!= 0) {
2165 "client %s has nonzero process callback status (%d)\n",
2166 client
->control
->name
, client
->control
->last_status
);
2171 DEBUG ("client %s errors = %d", client
->control
->name
,
2176 jack_engine_post_process (engine
);
2178 if (delayed_usecs
> engine
->control
->max_delayed_usecs
)
2179 engine
->control
->max_delayed_usecs
= delayed_usecs
;
2184 jack_unlock_graph (engine
);
2185 DEBUG("cycle finished, status = %d", ret
);
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
;
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;
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;
2251 /* normal condition */
2253 if (!no_increment
) {
2254 jack_inc_frame_time (engine
, nframes
);
2258 if (engine
->verbose
) {
2259 if (nframes
!= b_size
) {
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");
2278 jack_engine_delete (jack_engine_t
*engine
)
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
);
2330 pthread_cancel (engine
->server_thread
);
2331 pthread_join (engine
->server_thread
, NULL
);
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
);
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
);
2362 jack_messagebuffer_exit();
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
);
2381 jack_slist_free (port
->connections
);
2382 port
->connections
= 0;
2386 jack_deliver_event_to_all (jack_engine_t
*engine
, jack_event_t
*event
)
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
,
2396 jack_unlock_graph (engine
);
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
)
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
);
2426 jack_deliver_event (jack_engine_t
*engine
, jack_client_internal_t
*client
,
2427 jack_event_t
*event
)
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
);
2446 DEBUG ("client %s is still alive", client
->control
->name
);
2448 if (jack_client_is_internal (client
)) {
2450 switch (event
->type
) {
2452 case PortDisconnected
:
2453 jack_client_handle_port_connection
2454 (client
->private_client
, event
);
2457 case BufferSizeChange
:
2458 jack_client_invalidate_port_buffers
2459 (client
->private_client
);
2461 if (client
->control
->bufsize_cbset
) {
2462 client
->private_client
->bufsize
2464 client
->private_client
->bufsize_arg
);
2468 case SampleRateChange
:
2469 if (client
->control
->srate_cbset
) {
2470 client
->private_client
->srate
2472 client
->private_client
->srate_arg
);
2476 case GraphReordered
:
2477 if (client
->control
->graph_order_cbset
) {
2478 client
->private_client
->graph_order
2479 (client
->private_client
->graph_order_arg
);
2484 if (client
->control
->xrun_cbset
) {
2485 client
->private_client
->xrun
2486 (client
->private_client
->xrun_arg
);
2491 /* internal clients don't need to know */
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
,
2509 client
->error
+= JACK_ERROR_WITH_SOCKETS
;
2510 jack_lock_problems (engine
);
2512 jack_unlock_problems (engine
);
2515 if (client
->error
) {
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
;
2525 jack_time_t then
= jack_get_microseconds ();
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
));
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
);
2551 } else if (pfd
[0].revents
& POLLIN
) {
2553 /* client responded normally */
2555 DEBUG ("client event poll ok!");
2558 } else if (poll_ret
== 0) {
2560 /* no events, no errors, we woke up because poll()
2561 decided that time was up ...
2565 if (linux_poll_bug_encountered (engine
, then
, &poll_timeout
)) {
2569 if (poll_timeout
< 200) {
2570 VERBOSE (engine
, "FALSE WAKEUP skipped, remaining = %lld usec", poll_timeout
);
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
,
2590 if (read (client
->event_fd
, &status
, sizeof (status
)) != sizeof (status
)) {
2591 jack_error ("cannot read event response from "
2593 client
->control
->name
,
2595 client
->error
+= JACK_ERROR_WITH_SOCKETS
;
2596 jack_lock_problems (engine
);
2598 jack_unlock_problems (engine
);
2601 jack_error ("bad status (%d) for client %s "
2602 "handling event (type = %d)",
2604 client
->control
->name
,
2606 client
->error
+= JACK_ERROR_WITH_SOCKETS
;
2607 jack_lock_problems (engine
);
2609 jack_unlock_problems (engine
);
2613 DEBUG ("event delivered");
2619 jack_rechain_graph (jack_engine_t
*engine
)
2621 JSList
*node
, *next
;
2624 jack_client_internal_t
*client
, *subgraph_client
, *next_client
;
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 */
2652 if (((jack_client_internal_t
*)
2653 next
->data
)->control
->active
) {
2656 next
= jack_slist_next (next
);
2662 next_client
= (jack_client_internal_t
*)
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
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="
2686 subgraph_wait_fd
, n
);
2690 VERBOSE (engine
, "client %s: internal "
2691 "client, execution_order="
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;
2705 if (subgraph_client
== NULL
) {
2707 /* start a new subgraph. the
2708 * engine will start the chain
2709 * by writing to the nth
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"
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;
2733 VERBOSE (engine
, "client %s: in"
2734 " subgraph after %s, "
2737 client
->control
->name
,
2740 subgraph_client
->subgraph_wait_fd
= -1;
2742 /* this external client after
2743 this will have another
2744 client as its upstream
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
);
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()");
2778 static jack_nframes_t
2779 jack_get_port_total_latency (jack_engine_t
*engine
,
2780 jack_port_internal_t
*port
, int hop_count
,
2784 jack_nframes_t latency
;
2785 jack_nframes_t max_latency
= 0;
2787 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2791 for (i
= 0; i
< hop_count
; ++i
) {
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) {
2810 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2811 jack_info ("%sFor port %s (%s)", prefix
, port
->shared
->name
, (toward_port
? "toward" : "away"));
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
;
2823 (connection
->source
->shared
== port
->shared
)) ||
2825 (connection
->destination
->shared
== port
->shared
))) {
2827 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2828 jack_info ("%s\tskip connection %s->%s",
2830 connection
->source
->shared
->name
,
2831 connection
->destination
->shared
->name
);
2837 #ifdef DEBUG_TOTAL_LATENCY_COMPUTATION
2838 jack_info ("%s\tconnection %s->%s ... ",
2840 connection
->source
->shared
->name
,
2841 connection
->destination
->shared
->name
);
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
->
2855 jack_get_port_total_latency (
2856 engine
, connection
->source
,
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
->
2871 jack_get_port_total_latency (
2873 connection
->destination
,
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
);
2888 return latency
+ max_latency
;
2892 jack_compute_port_total_latency (jack_engine_t
* engine
, jack_port_shared_t
* port
)
2895 port
->total_latency
=
2896 jack_get_port_total_latency (
2897 engine
, &engine
->internal_ports
[port
->id
],
2898 0, !(port
->flags
& JackPortIsOutput
));
2903 jack_compute_all_port_total_latencies (jack_engine_t
*engine
)
2905 jack_port_shared_t
*shared
= engine
->control
->ports
;
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
;
2916 shared
[i
].total_latency
=
2917 jack_get_port_total_latency (
2918 engine
, &engine
->internal_ports
[i
],
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
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
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.
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");
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
)) {
2974 } else if (jack_client_feeds_transitive (b
, a
) ||
2975 (b
->control
->type
== ClientDriver
&&
2976 a
->control
->type
!= ClientDriver
)) {
2983 /* transitive closure of the relation expressed by the sortfeeds lists. */
2985 jack_client_feeds_transitive (jack_client_internal_t
*source
,
2986 jack_client_internal_t
*dest
)
2988 jack_client_internal_t
*med
;
2991 if (jack_slist_find (source
->sortfeeds
, dest
)) {
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
)) {
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.
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
;
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
;
3034 /* find out whether a normal sort would have been possible */
3035 while (unsortedclients
&& !stuck
) {
3039 for (srcnode
= engine
->clients
; srcnode
;
3040 srcnode
= jack_slist_next (srcnode
)) {
3042 src
= (jack_client_internal_t
*) srcnode
->data
;
3044 if (!src
->tfedcount
) {
3048 src
->tfedcount
= -1;
3050 for (dstnode
= src
->truefeeds
; dstnode
;
3051 dstnode
= jack_slist_next (dstnode
)) {
3053 dst
= (jack_client_internal_t
*)
3063 VERBOSE (engine
, "graph is still cyclic" );
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
*)
3085 if (conn
->dir
== -1 )
3088 conn->srcclient == src) */{
3091 "reversing connection from "
3093 conn
->srcclient
->control
->name
,
3094 conn
->dstclient
->control
->name
);
3096 conn
->dstclient
->sortfeeds
=
3098 (conn
->dstclient
->sortfeeds
,
3101 conn
->srcclient
->sortfeeds
=
3103 (conn
->srcclient
->sortfeeds
,
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
;
3125 jack_info ("engine.c: <-- dump begins -->");
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",
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
;
3155 jack_slist_next (connectionnode
)) {
3156 connection
= (jack_connection_internal_t
*)
3157 connectionnode
->data
;
3159 jack_info("\t\t connection #%d: %s %s",
3161 (port
->shared
->flags
3162 & JackPortIsInput
)? "<-": "->",
3163 (port
->shared
->flags
& JackPortIsInput
)?
3164 connection
->source
->shared
->name
:
3165 connection
->destination
->shared
->name
);
3171 jack_unlock_graph (engine
);
3175 jack_info("engine.c: <-- dump ends -->");
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
;
3189 if ((srcport
= jack_get_port_by_name (engine
, source_port
)) == NULL
) {
3190 jack_error ("unknown source port in attempted connection [%s]",
3195 if ((dstport
= jack_get_port_by_name (engine
, destination_port
))
3197 jack_error ("unknown destination port in attempted connection"
3198 " [%s]", destination_port
);
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
);
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
);
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");
3222 if ((srcclient
= jack_client_internal_by_id (engine
,
3223 srcport
->shared
->client_id
))
3225 jack_error ("unknown client set as owner of port - "
3230 if (!srcclient
->control
->active
) {
3231 jack_error ("cannot connect ports owned by inactive clients;"
3232 " \"%s\" is not active", srcclient
->control
->name
);
3236 if ((dstclient
= jack_client_internal_by_id (engine
,
3237 dstport
->shared
->client_id
))
3239 jack_error ("unknown client set as owner of port - cannot "
3244 if (!dstclient
->control
->active
) {
3245 jack_error ("cannot connect ports owned by inactive clients;"
3246 " \"%s\" is not active", dstclient
->control
->name
);
3250 for (it
= srcport
->connections
; it
; it
= it
->next
) {
3251 if (((jack_connection_internal_t
*)it
->data
)->destination
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
);
3276 jack_unlock_graph (engine
);
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
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
,
3305 (dstclient
->control
->type
== ClientDriver
&&
3306 srcclient
->control
->type
!= ClientDriver
)) {
3308 /* dest is running before source so
3309 this is a feedback connection */
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
++;
3322 "feedback count up to %d",
3323 engine
->feedbackcount
);
3327 /* this is not a feedback connection */
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;
3342 /* this is a connection to self */
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
);
3381 jack_port_disconnect_internal (jack_engine_t
*engine
,
3382 jack_port_internal_t
*srcport
,
3383 jack_port_internal_t
*dstport
)
3387 jack_connection_internal_t
*connect
;
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
,
3408 dstport
->connections
=
3409 jack_slist_remove (dstport
->connections
,
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
3423 if (srcport
->connections
== NULL
) {
3424 srcport
->shared
->monitor_requests
= 0;
3427 jack_send_connection_notification (
3428 engine
, srcport
->shared
->client_id
, src_id
,
3430 jack_send_connection_notification (
3431 engine
, dstport
->shared
->client_id
, dst_id
,
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);
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
);
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
);
3460 /* feedback connection: remove source
3461 from dest's sortfeeds list */
3462 dst
->sortfeeds
= jack_slist_remove
3463 (dst
->sortfeeds
, src
);
3464 engine
->feedbackcount
--;
3466 "feedback count down to %d",
3467 engine
->feedbackcount
);
3470 } /* else self-connection: do nothing */
3478 if (check_acyclic
) {
3479 jack_check_acyclic (engine
);
3482 jack_sort_graph (engine
);
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
);
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
);
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
;
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
);
3522 if ((dstport
= jack_get_port_by_name (engine
, destination_port
))
3524 jack_error ("unknown destination port in attempted"
3525 " disconnection [%s]", destination_port
);
3529 jack_lock_graph (engine
);
3531 ret
= jack_port_disconnect_internal (engine
, srcport
, dstport
);
3533 jack_unlock_graph (engine
);
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
,
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
,
3561 jack_error ("cannot check on FIFO %d\n", which_fifo
);
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
);
3572 if (which_fifo
>= engine
->fifo_size
) {
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
,
3591 DEBUG ("opened engine->fifo[%d] == %d (%s)",
3592 which_fifo
, engine
->fifo
[which_fifo
], path
);
3595 return engine
->fifo
[which_fifo
];
3599 jack_clear_fifos (jack_engine_t
*engine
)
3601 /* caller must hold client_lock */
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
));
3623 jack_use_driver (jack_engine_t
*engine
, jack_driver_t
*driver
)
3625 if (engine
->driver
) {
3626 engine
->driver
->detach (engine
->driver
, engine
);
3631 engine
->driver
= driver
;
3633 if (driver
->attach (driver
, engine
)) {
3638 engine
->rolling_interval
=
3639 jack_rolling_interval (driver
->period_usecs
);
3646 /* PORT RELATED FUNCTIONS */
3649 static jack_port_id_t
3650 jack_get_free_port (jack_engine_t
*engine
)
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;
3664 pthread_mutex_unlock (&engine
->port_lock
);
3666 if (i
== engine
->port_max
) {
3667 return (jack_port_id_t
) -1;
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
);
3686 jack_slist_prepend (blist
->freelist
,
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
)
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
)) {
3707 pthread_mutex_unlock (&engine
->port_lock
);
3709 if (id
!= engine
->port_max
) {
3710 return &engine
->internal_ports
[id
];
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
;
3724 char *backend_client_name
;
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) {
3734 if (i
== engine
->control
->n_port_types
) {
3735 jack_error ("cannot register a port of type \"%s\"",
3736 req
->x
.port_info
.type
);
3740 jack_lock_graph (engine
);
3741 if ((client
= jack_client_internal_by_id (engine
,
3742 req
->x
.port_info
.client_id
))
3744 jack_error ("unknown client id in port registration request");
3745 jack_unlock_graph (engine
);
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
);
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
);
3761 shared
= &engine
->control
->ports
[port_id
];
3763 if (!internal
|| !engine
->driver
)
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)
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
);
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
);
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
);
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
);
3800 strcpy (shared
->name
, req
->x
.port_info
.name
);
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
);
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
;
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
);
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
);
3858 jack_lock_graph (engine
);
3859 if ((client
= jack_client_internal_by_id (engine
, shared
->client_id
))
3861 jack_error ("unknown client id in port registration request");
3862 jack_unlock_graph (engine
);
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
,
3875 jack_unlock_graph (engine
);
3881 jack_do_get_port_connections (jack_engine_t
*engine
, jack_request_t
*req
,
3884 jack_port_internal_t
*port
;
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
);
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
3905 internal
= jack_client_is_internal(
3906 (jack_client_internal_t
*) node
->data
);
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
));
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
3934 port_id
= ((jack_connection_internal_t
*)
3935 node
->data
)->destination
->shared
->id
;
3937 port_id
= ((jack_connection_internal_t
*)
3938 node
->data
)->source
->shared
->id
;
3943 /* internal client asking for
3944 * names. store in malloc'ed space,
3947 char **ports
= req
->x
.port_connections
.ports
;
3950 engine
->control
->ports
[port_id
].name
;
3954 /* external client asking for
3955 * names. we write the port id's to
3958 if (write (reply_fd
, &port_id
,
3960 < (ssize_t
) sizeof (port_id
)) {
3961 jack_error ("cannot write port id "
3973 jack_unlock_graph (engine
);
3978 jack_port_registration_notify (jack_engine_t
*engine
,
3979 jack_port_id_t port_id
, int yn
)
3982 jack_client_internal_t
*client
;
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
) {
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
,
4008 jack_client_registration_notify (jack_engine_t
*engine
,
4009 const char* name
, int yn
)
4012 jack_client_internal_t
*client
;
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
) {
4026 if (strcmp ((char*) client
->control
->name
, (char*) name
) == 0) {
4027 /* do not notify client of its own registration */
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
,
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;
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
);
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
);
4075 static jack_port_internal_t
*
4076 jack_get_port_by_name (jack_engine_t
*engine
, const char *name
)
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
];
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
;
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
);
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
));