1 /* -*- mode: c; c-file-style: "bsd"; -*- */
3 Copyright (C) 2001-2003 Paul Davis
4 Copyright (C) 2005 Jussi Laako
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include <sys/types.h>
36 #include <sys/socket.h>
40 #include <jack/internal.h>
41 #include <jack/jack.h>
42 #include <jack/engine.h>
43 #include <jack/pool.h>
44 #include <jack/jslist.h>
45 #include <jack/version.h>
47 #include <jack/unlock.h>
48 #include <jack/thread.h>
49 #include <jack/varargs.h>
50 #include <jack/intsimd.h>
52 #include <sysdeps/time.h>
56 #include <sysdeps/poll.h>
57 #include <sysdeps/ipc.h>
58 #include <sysdeps/cycles.h>
60 #ifdef JACK_USE_MACH_THREADS
61 #include <sysdeps/pThreadUtilities.h>
64 static pthread_mutex_t client_lock
;
65 static pthread_cond_t client_ready
;
68 jack_client_close_aux (jack_client_t
*client
);
70 #define EVENT_POLL_INDEX 0
71 #define WAIT_POLL_INDEX 1
72 #define event_fd pollfd[EVENT_POLL_INDEX].fd
73 #define graph_wait_fd pollfd[WAIT_POLL_INDEX].fd
77 struct _jack_client
*client
;
78 const char *client_name
;
90 cpu_type
= ((have_3dnow() << 8) | have_sse());
91 if (ARCH_X86_HAVE_3DNOW(cpu_type
))
92 jack_info("Enhanced3DNow! detected");
93 if (ARCH_X86_HAVE_SSE2(cpu_type
))
94 jack_info("SSE2 detected");
95 if ((!ARCH_X86_HAVE_3DNOW(cpu_type
)) && (!ARCH_X86_HAVE_SSE2(cpu_type
)))
96 jack_info("No supported SIMD instruction sets detected");
97 jack_port_set_funcs();
105 jack_port_set_funcs();
108 #endif /* ARCH_X86 */
110 #endif /* USE_DYNSIMD */
112 char *jack_tmpdir
= DEFAULT_TMP_DIR
;
119 char buf
[PATH_MAX
+2]; /* allow tmpdir to live anywhere, plus newline, plus null */
124 /* some implementations of popen(3) close a security loophole by
125 resetting PATH for the exec'd command. since we *want* to
126 use the user's PATH setting to locate jackd, we have to
130 if ((pathenv
= getenv ("PATH")) == 0) {
134 /* don't let strtok(3) mess with the real environment variable */
136 pathcopy
= strdup (pathenv
);
137 p
= strtok (pathcopy
, ":");
140 char jackd
[PATH_MAX
+1];
141 char command
[PATH_MAX
+4];
143 snprintf (jackd
, sizeof (jackd
), "%s/jackd", p
);
145 if (access (jackd
, X_OK
) == 0) {
147 snprintf (command
, sizeof (command
), "%s -l", jackd
);
149 if ((in
= popen (command
, "r")) != NULL
) {
154 p
= strtok (NULL
, ":");
158 /* no command successfully started */
163 if (fgets (buf
, sizeof (buf
), in
) == NULL
) {
171 if (buf
[len
-1] != '\n') {
172 /* didn't get a whole line */
178 jack_tmpdir
= (char *) malloc (len
);
179 memcpy (jack_tmpdir
, buf
, len
-1);
180 jack_tmpdir
[len
-1] = '\0';
188 jack_error (const char *fmt
, ...)
194 vsnprintf (buffer
, sizeof(buffer
), fmt
, ap
);
195 jack_error_callback (buffer
);
200 default_jack_error_callback (const char *desc
)
205 fprintf(stderr
, "%s\n", desc
);
211 default_jack_info_callback (const char *desc
)
213 fprintf(stdout
, "%s\n", desc
);
218 silent_jack_error_callback (const char *desc
)
222 void (*jack_error_callback
)(const char *desc
) = &default_jack_error_callback
;
223 void (*jack_info_callback
)(const char *desc
) = &default_jack_info_callback
;
226 jack_info (const char *fmt
, ...)
232 vsnprintf (buffer
, sizeof(buffer
), fmt
, ap
);
233 jack_info_callback (buffer
);
238 oop_client_deliver_request (void *ptr
, jack_request_t
*req
)
241 jack_client_t
*client
= (jack_client_t
*) ptr
;
243 wok
= (write (client
->request_fd
, req
, sizeof (*req
))
245 rok
= (read (client
->request_fd
, req
, sizeof (*req
))
248 if (wok
&& rok
) { /* everything OK? */
252 req
->status
= -1; /* request failed */
254 /* check for server shutdown */
255 if (client
->engine
->engine_ok
== 0)
258 /* otherwise report errors */
260 jack_error ("cannot send request type %d to server",
263 jack_error ("cannot read result for request type %d from"
264 " server (%s)", req
->type
, strerror (errno
));
269 jack_client_deliver_request (const jack_client_t
*client
, jack_request_t
*req
)
271 /* indirect through the function pointer that was set either
272 * by jack_client_open() or by jack_new_client_request() in
276 return client
->deliver_request (client
->deliver_arg
,
280 #if JACK_USE_MACH_THREADS
285 jack_client_t
*client
;
287 client
= (jack_client_t
*) malloc (sizeof (jack_client_t
));
288 client
->pollfd
= (struct pollfd
*) malloc (sizeof (struct pollfd
) * 1);
290 client
->request_fd
= -1;
291 client
->event_fd
= -1;
292 client
->upstream_is_jackd
= 0;
293 client
->graph_wait_fd
= -1;
294 client
->graph_next_fd
= -1;
295 client
->ports
= NULL
;
296 client
->ports_ext
= NULL
;
297 client
->engine
= NULL
;
298 client
->control
= NULL
;
299 client
->thread_ok
= FALSE
;
300 client
->rt_thread_ok
= FALSE
;
301 client
->first_active
= TRUE
;
302 client
->on_shutdown
= NULL
;
303 client
->n_port_types
= 0;
304 client
->port_segment
= NULL
;
313 jack_client_t
*client
;
315 client
= (jack_client_t
*) malloc (sizeof (jack_client_t
));
316 client
->pollfd
= (struct pollfd
*) malloc (sizeof (struct pollfd
) * 2);
318 client
->request_fd
= -1;
319 client
->event_fd
= -1;
320 client
->upstream_is_jackd
= 0;
321 client
->graph_wait_fd
= -1;
322 client
->graph_next_fd
= -1;
323 client
->ports
= NULL
;
324 client
->ports_ext
= NULL
;
325 client
->engine
= NULL
;
326 client
->control
= NULL
;
327 client
->thread_ok
= FALSE
;
328 client
->first_active
= TRUE
;
329 client
->on_shutdown
= NULL
;
330 client
->n_port_types
= 0;
331 client
->port_segment
= NULL
;
335 #endif /* USE_DYNSIMD */
343 * Build the jack_client_t structure for an internal client.
346 jack_client_alloc_internal (jack_client_control_t
*cc
, jack_engine_t
* engine
)
348 jack_client_t
* client
;
350 client
= jack_client_alloc ();
352 client
->control
= cc
;
353 client
->engine
= engine
->control
;
355 client
->n_port_types
= client
->engine
->n_port_types
;
356 client
->port_segment
= &engine
->port_segment
[0];
362 jack_client_free (jack_client_t
*client
)
364 if (client
->pollfd
) {
365 free (client
->pollfd
);
372 jack_client_invalidate_port_buffers (jack_client_t
*client
)
377 /* This releases all local memory owned by input ports
378 and sets the buffer pointer to NULL. This will cause
379 jack_port_get_buffer() to reallocate space for the
380 buffer on the next call (if there is one).
383 for (node
= client
->ports
; node
; node
= jack_slist_next (node
)) {
384 port
= (jack_port_t
*) node
->data
;
386 if (port
->shared
->flags
& JackPortIsInput
) {
387 if (port
->mix_buffer
) {
388 jack_pool_release (port
->mix_buffer
);
389 port
->mix_buffer
= NULL
;
396 jack_client_handle_port_connection (jack_client_t
*client
, jack_event_t
*event
)
398 jack_port_t
*control_port
;
399 jack_port_t
*other
= 0;
401 int need_free
= FALSE
;
403 if (client
->engine
->ports
[event
->x
.self_id
].client_id
== client
->control
->id
||
404 client
->engine
->ports
[event
->y
.other_id
].client_id
== client
->control
->id
) {
406 /* its one of ours */
408 switch (event
->type
) {
410 other
= jack_port_new (client
, event
->y
.other_id
,
412 /* jack_port_by_id_int() always returns an internal
413 * port that does not need to be deallocated
415 control_port
= jack_port_by_id_int (client
, event
->x
.self_id
,
417 pthread_mutex_lock (&control_port
->connection_lock
);
418 control_port
->connections
=
419 jack_slist_prepend (control_port
->connections
,
421 pthread_mutex_unlock (&control_port
->connection_lock
);
424 case PortDisconnected
:
425 /* jack_port_by_id_int() always returns an internal
426 * port that does not need to be deallocated
428 control_port
= jack_port_by_id_int (client
, event
->x
.self_id
,
430 pthread_mutex_lock (&control_port
->connection_lock
);
432 for (node
= control_port
->connections
; node
;
433 node
= jack_slist_next (node
)) {
435 other
= (jack_port_t
*) node
->data
;
437 if (other
->shared
->id
== event
->y
.other_id
) {
438 control_port
->connections
=
439 jack_slist_remove_link (
440 control_port
->connections
,
442 jack_slist_free_1 (node
);
448 pthread_mutex_unlock (&control_port
->connection_lock
);
457 if (client
->control
->port_connect_cbset
) {
458 client
->port_connect (event
->x
.self_id
, event
->y
.other_id
,
459 (event
->type
== PortConnected
? 1 : 0),
460 client
->port_connect_arg
);
466 #if JACK_USE_MACH_THREADS
469 jack_handle_reorder (jack_client_t
*client
, jack_event_t
*event
)
473 /* If the client registered its own callback for graph order events,
477 if (client
->control
->graph_order
) {
478 client
->control
->graph_order (client
->control
->graph_order_arg
);
487 jack_handle_reorder (jack_client_t
*client
, jack_event_t
*event
)
489 char path
[PATH_MAX
+1];
491 DEBUG ("graph reorder\n");
493 if (client
->graph_wait_fd
>= 0) {
494 DEBUG ("closing graph_wait_fd==%d", client
->graph_wait_fd
);
495 close (client
->graph_wait_fd
);
496 client
->graph_wait_fd
= -1;
499 if (client
->graph_next_fd
>= 0) {
500 DEBUG ("closing graph_next_fd==%d", client
->graph_next_fd
);
501 close (client
->graph_next_fd
);
502 client
->graph_next_fd
= -1;
505 sprintf (path
, "%s-%" PRIu32
, client
->fifo_prefix
, event
->x
.n
);
507 if ((client
->graph_wait_fd
= open (path
, O_RDONLY
|O_NONBLOCK
)) < 0) {
508 jack_error ("cannot open specified fifo [%s] for reading (%s)",
509 path
, strerror (errno
));
512 DEBUG ("opened new graph_wait_fd %d (%s)", client
->graph_wait_fd
, path
);
514 sprintf (path
, "%s-%" PRIu32
, client
->fifo_prefix
, event
->x
.n
+1);
516 if ((client
->graph_next_fd
= open (path
, O_WRONLY
|O_NONBLOCK
)) < 0) {
517 jack_error ("cannot open specified fifo [%s] for writing (%s)",
518 path
, strerror (errno
));
522 client
->upstream_is_jackd
= event
->y
.n
;
525 DEBUG ("opened new graph_next_fd %d (%s) (upstream is jackd? %d)",
526 client
->graph_next_fd
, path
,
527 client
->upstream_is_jackd
);
529 /* If the client registered its own callback for graph order events,
533 if (client
->control
->graph_order_cbset
) {
534 client
->graph_order (client
->graph_order_arg
);
543 server_connect (const char *server_name
)
546 struct sockaddr_un addr
;
549 char server_dir
[PATH_MAX
+1] = "";
551 if ((fd
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0) {
552 jack_error ("cannot create client socket (%s)",
557 //JOQ: temporary debug message
558 //jack_info ("DEBUG: connecting to `%s' server", server_name);
560 addr
.sun_family
= AF_UNIX
;
561 snprintf (addr
.sun_path
, sizeof (addr
.sun_path
) - 1, "%s/jack_%d",
562 jack_server_dir (server_name
, server_dir
) , which
);
564 if (connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
573 server_event_connect (jack_client_t
*client
, const char *server_name
)
576 struct sockaddr_un addr
;
577 jack_client_connect_ack_request_t req
;
578 jack_client_connect_ack_result_t res
;
580 char server_dir
[PATH_MAX
+1] = "";
582 if ((fd
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0) {
583 jack_error ("cannot create client event socket (%s)",
588 addr
.sun_family
= AF_UNIX
;
589 snprintf (addr
.sun_path
, sizeof (addr
.sun_path
) - 1, "%s/jack_ack_0",
590 jack_server_dir (server_name
,server_dir
));
592 if (connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
593 jack_error ("cannot connect to jack server for events",
599 req
.client_id
= client
->control
->id
;
601 if (write (fd
, &req
, sizeof (req
)) != sizeof (req
)) {
602 jack_error ("cannot write event connect request to server (%s)",
608 if (read (fd
, &res
, sizeof (res
)) != sizeof (res
)) {
609 jack_error ("cannot read event connect result from server (%s)",
615 if (res
.status
!= 0) {
616 jack_error ("cannot connect to server for event stream (%s)",
625 /* Exec the JACK server in this process. Does not return. */
627 _start_server (const char *server_name
)
641 snprintf(filename
, 255, "%s/.jackdrc", getenv("HOME"));
642 fp
= fopen(filename
, "r");
645 fp
= fopen("/etc/jackdrc", "r");
647 /* if still not found, check old config name for backwards compatability */
649 fp
= fopen("/etc/jackd.conf", "r");
654 ret
= fscanf(fp
, "%s", buffer
);
655 while(ret
!= 0 && ret
!= EOF
) {
656 strcat(arguments
, buffer
);
657 strcat(arguments
, " ");
658 ret
= fscanf(fp
, "%s", buffer
);
660 if (strlen(arguments
) > 0) {
666 #if defined(USE_CAPABILITIES)
667 command
= JACK_LOCATION
"/jackstart";
668 strncpy(arguments
, JACK_LOCATION
"/jackstart -T -R -d "
669 JACK_DEFAULT_DRIVER
" -p 512", 255);
670 #else /* !USE_CAPABILITIES */
671 command
= JACK_LOCATION
"/jackd";
672 strncpy(arguments
, JACK_LOCATION
"/jackd -T -d "
673 JACK_DEFAULT_DRIVER
, 255);
674 #endif /* USE_CAPABILITIES */
676 result
= strcspn(arguments
, " ");
677 command
= (char *) malloc(result
+1);
678 strncpy(command
, arguments
, result
);
679 command
[result
] = '\0';
682 argv
= (char **) malloc (255);
685 /* insert -T and -nserver_name in front of arguments */
687 argv
[i
] = (char *) malloc(strlen ("-T") + 1);
688 strcpy (argv
[i
++], "-T");
690 size_t optlen
= strlen ("-n");
693 + strlen (server_name
) + 1);
695 strcpy (buf
+optlen
, server_name
);
700 result
= strcspn(arguments
+pos
, " ");
704 argv
[i
] = (char*)malloc(result
+1);
706 strncpy(argv
[i
], arguments
+pos
, result
);
707 argv
[i
][result
] = '\0';
715 fprintf (stderr
, "execing JACK using %s\n", command
);
716 for (_xx
= 0; argv
[_xx
]; ++_xx
) {
717 fprintf (stderr
, "\targv[%d] = %s\n", _xx
, argv
[_xx
]);
721 execv (command
, argv
);
723 /* If execv() succeeds, it does not return. There's no point
724 * in calling jack_error() here in the child process. */
725 fprintf (stderr
, "exec of JACK server (command = \"%s\") failed: %s\n", command
, strerror (errno
));
729 start_server (const char *server_name
, jack_options_t options
)
731 if ((options
& JackNoStartServer
)
732 || getenv("JACK_NO_START_SERVER")) {
736 /* The double fork() forces the server to become a child of
737 * init, which will always clean up zombie process state on
738 * termination. This even works in cases where the server
739 * terminates but this client does not.
741 * Since fork() is usually implemented using copy-on-write
742 * virtual memory tricks, the overhead of the second fork() is
743 * probably relatively small.
746 case 0: /* child process */
748 case 0: /* grandchild process */
749 _start_server(server_name
);
750 _exit (99); /* exec failed */
756 case -1: /* fork() error */
757 return 1; /* failed to start server */
760 /* only the original parent process goes here */
761 return 0; /* (probably) successful */
765 jack_request_client (ClientType type
,
766 const char* client_name
, jack_options_t options
,
767 jack_status_t
*status
, jack_varargs_t
*va
,
768 jack_client_connect_result_t
*res
, int *req_fd
)
770 jack_client_connect_request_t req
;
773 memset (&req
, 0, sizeof (req
));
774 req
.options
= options
;
776 if (strlen (client_name
) >= sizeof (req
.name
)) {
777 jack_error ("\"%s\" is too long to be used as a JACK client"
779 "Please use %lu characters or less.",
780 client_name
, sizeof (req
.name
));
785 && (strlen (va
->load_name
) > sizeof (req
.object_path
) - 1)) {
786 jack_error ("\"%s\" is too long to be used as a JACK shared"
788 "Please use %lu characters or less.",
789 va
->load_name
, sizeof (req
.object_path
) - 1);
794 && (strlen (va
->load_init
) > sizeof (req
.object_data
) - 1)) {
795 jack_error ("\"%s\" is too long to be used as a JACK shared"
796 " object data string.\n"
797 "Please use %lu characters or less.",
798 va
->load_init
, sizeof (req
.object_data
) - 1);
802 if ((*req_fd
= server_connect (va
->server_name
)) < 0) {
804 if (start_server(va
->server_name
, options
)) {
805 *status
|= (JackFailure
|JackServerFailed
);
812 *status
|= (JackFailure
|JackServerFailed
);
815 } while ((*req_fd
= server_connect (va
->server_name
)) < 0);
816 *status
|= JackServerStarted
;
819 /* format connection request */
821 req
.protocol_v
= jack_protocol_version
;
824 snprintf (req
.name
, sizeof (req
.name
),
826 snprintf (req
.object_path
, sizeof (req
.object_path
),
827 "%s", va
->load_name
);
828 snprintf (req
.object_data
, sizeof (req
.object_data
),
829 "%s", va
->load_init
);
831 if (write (*req_fd
, &req
, sizeof (req
)) != sizeof (req
)) {
832 jack_error ("cannot send request to jack server (%s)",
834 *status
|= (JackFailure
|JackServerError
);
838 if (read (*req_fd
, res
, sizeof (*res
)) != sizeof (*res
)) {
841 /* server shut the socket */
842 jack_error ("could not attach as client");
843 *status
|= (JackFailure
|JackServerError
);
847 if (errno
== ECONNRESET
) {
848 jack_error ("could not attach as JACK client "
849 "(server has exited)");
850 *status
|= (JackFailure
|JackServerError
);
854 jack_error ("cannot read response from jack server (%s)",
856 *status
|= (JackFailure
|JackServerError
);
860 *status
|= res
->status
; /* return server status bits */
862 if (*status
& JackFailure
) {
863 if (*status
& JackVersionError
) {
864 jack_error ("client linked with incompatible libjack"
867 jack_error ("could not attach to JACK server");
868 *status
|= JackServerError
;
894 jack_attach_port_segment (jack_client_t
*client
, jack_port_type_id_t ptid
)
896 /* Lookup, attach and register the port/buffer segments in use
900 if (client
->control
->type
!= ClientExternal
) {
901 jack_error("Only external clients need attach port segments");
905 /* make sure we have space to store the port
909 if (ptid
>= client
->n_port_types
) {
911 client
->port_segment
= (jack_shm_info_t
*)
912 realloc (client
->port_segment
,
913 sizeof (jack_shm_info_t
) * (ptid
+1));
915 memset (&client
->port_segment
[client
->n_port_types
],
917 sizeof (jack_shm_info_t
) *
918 (ptid
- client
->n_port_types
));
920 client
->n_port_types
= ptid
+ 1;
924 /* release any previous segment */
925 jack_release_shm (&client
->port_segment
[ptid
]);
928 /* get the index into the shm registry */
930 client
->port_segment
[ptid
].index
=
931 client
->engine
->port_types
[ptid
].shm_registry_index
;
933 /* attach the relevant segment */
935 if (jack_attach_shm (&client
->port_segment
[ptid
])) {
936 jack_error ("cannot attach port segment shared memory"
937 " (%s)", strerror (errno
));
945 jack_client_open_aux (const char *client_name
,
946 jack_options_t options
,
947 jack_status_t
*status
, va_list ap
)
949 /* optional arguments: */
950 jack_varargs_t va
; /* variable arguments */
954 jack_client_connect_result_t res
;
955 jack_client_t
*client
;
956 jack_port_type_id_t ptid
;
957 jack_status_t my_status
;
959 jack_messagebuffer_init ();
961 if (status
== NULL
) /* no status from caller? */
962 status
= &my_status
; /* use local status word */
965 /* validate parameters */
966 if ((options
& ~JackOpenOptions
)) {
967 *status
|= (JackFailure
|JackInvalidOption
);
971 /* parse variable arguments */
973 jack_varargs_parse(options
, ap
, &va
);
975 jack_varargs_init(&va
);
977 /* External clients need to know where the tmpdir used for
978 communication with the server lives
980 if (jack_get_tmpdir ()) {
981 *status
|= JackFailure
;
985 /* External clients need this initialized. It is already set
986 * up in the server's address space for internal clients.
990 if (jack_request_client (ClientExternal
, client_name
, options
, status
,
991 &va
, &res
, &req_fd
)) {
995 /* Allocate the jack_client_t structure in local memory.
996 * Shared memory is not accessible yet. */
997 client
= jack_client_alloc ();
998 strcpy (client
->name
, res
.name
);
999 strcpy (client
->fifo_prefix
, res
.fifo_prefix
);
1000 client
->request_fd
= req_fd
;
1001 client
->pollfd
[EVENT_POLL_INDEX
].events
=
1002 POLLIN
|POLLERR
|POLLHUP
|POLLNVAL
;
1003 #ifndef JACK_USE_MACH_THREADS
1004 client
->pollfd
[WAIT_POLL_INDEX
].events
=
1005 POLLIN
|POLLERR
|POLLHUP
|POLLNVAL
;
1008 /* Don't access shared memory until server connected. */
1009 if (jack_initialize_shm (va
.server_name
)) {
1010 jack_error ("Unable to initialize shared memory.");
1011 *status
|= (JackFailure
|JackShmFailure
);
1015 /* attach the engine control/info block */
1016 client
->engine_shm
.index
= res
.engine_shm_index
;
1017 if (jack_attach_shm (&client
->engine_shm
)) {
1018 jack_error ("cannot attached engine control shared memory"
1023 client
->engine
= (jack_control_t
*) jack_shm_addr (&client
->engine_shm
);
1025 /* initialize clock source as early as possible */
1026 jack_set_clock_source (client
->engine
->clock_source
);
1028 /* now attach the client control block */
1029 client
->control_shm
.index
= res
.client_shm_index
;
1030 if (jack_attach_shm (&client
->control_shm
)) {
1031 jack_error ("cannot attached client control shared memory"
1036 client
->control
= (jack_client_control_t
*)
1037 jack_shm_addr (&client
->control_shm
);
1039 /* Nobody else needs to access this shared memory any more, so
1040 * destroy it. Because we have it attached, it won't vanish
1041 * till we exit (and release it).
1043 jack_destroy_shm (&client
->control_shm
);
1045 client
->n_port_types
= client
->engine
->n_port_types
;
1046 client
->port_segment
= (jack_shm_info_t
*)
1047 malloc (sizeof (jack_shm_info_t
) * client
->n_port_types
);
1049 for (ptid
= 0; ptid
< client
->n_port_types
; ++ptid
) {
1050 client
->port_segment
[ptid
].index
=
1051 client
->engine
->port_types
[ptid
].shm_registry_index
;
1052 client
->port_segment
[ptid
].attached_at
= MAP_FAILED
;
1053 jack_attach_port_segment (client
, ptid
);
1056 /* set up the client so that it does the right thing for an
1059 client
->deliver_request
= oop_client_deliver_request
;
1060 client
->deliver_arg
= client
;
1062 if ((ev_fd
= server_event_connect (client
, va
.server_name
)) < 0) {
1066 client
->event_fd
= ev_fd
;
1068 #ifdef JACK_USE_MACH_THREADS
1069 /* specific resources for server/client real-time thread
1071 client
->clienttask
= mach_task_self();
1073 if (task_get_bootstrap_port(client
->clienttask
, &client
->bp
)){
1074 jack_error ("Can't find bootstrap port");
1078 if (allocate_mach_clientport(client
, res
.portnum
) < 0) {
1079 jack_error("Can't allocate mach port");
1082 #endif /* JACK_USE_MACH_THREADS */
1086 if (client
->engine
) {
1087 jack_release_shm (&client
->engine_shm
);
1090 if (client
->control
) {
1091 jack_release_shm (&client
->control_shm
);
1092 client
->control
= 0;
1105 jack_client_t
* jack_client_open(const char* ext_client_name
, jack_options_t options
, jack_status_t
* status
, ...)
1108 va_start(ap
, status
);
1109 jack_client_t
* res
= jack_client_open_aux(ext_client_name
, options
, status
, ap
);
1115 jack_client_new (const char *client_name
)
1117 jack_options_t options
= JackUseExactName
;
1118 if (getenv("JACK_START_SERVER") == NULL
)
1119 options
|= JackNoStartServer
;
1120 return jack_client_open_aux (client_name
, options
, NULL
, NULL
);
1124 jack_get_client_name (jack_client_t
*client
)
1126 return client
->name
;
1130 jack_internal_client_new (const char *client_name
,
1131 const char *so_name
, const char *so_data
)
1133 jack_client_connect_result_t res
;
1136 jack_status_t status
;
1137 jack_options_t options
= JackUseExactName
;
1139 if (getenv("JACK_START_SERVER") == NULL
)
1140 options
|= JackNoStartServer
;
1142 jack_varargs_init (&va
);
1143 va
.load_name
= (char *) so_name
;
1144 va
.load_init
= (char *) so_data
;
1146 return jack_request_client (ClientInternal
, client_name
,
1147 options
, &status
, &va
, &res
, &req_fd
);
1151 jack_default_server_name (void)
1154 if ((server_name
= getenv("JACK_DEFAULT_SERVER")) == NULL
)
1155 server_name
= "default";
1159 /* returns the name of the per-user subdirectory of jack_tmpdir */
1161 jack_user_dir (void)
1163 static char user_dir
[PATH_MAX
+1] = "";
1165 /* format the path name on the first call */
1166 if (user_dir
[0] == '\0') {
1167 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
1168 snprintf (user_dir
, sizeof (user_dir
), "%s/jack",
1171 snprintf (user_dir
, sizeof (user_dir
), "%s/jack-%d",
1172 jack_tmpdir
, getuid ());
1179 /* returns the name of the per-server subdirectory of jack_user_dir() */
1181 jack_server_dir (const char *server_name
, char *server_dir
)
1183 /* format the path name into the suppled server_dir char array,
1184 * assuming that server_dir is at least as large as PATH_MAX+1 */
1186 snprintf (server_dir
, PATH_MAX
+1, "%s/%s",
1187 jack_user_dir (), server_name
);
1193 jack_internal_client_close (const char *client_name
)
1195 jack_client_connect_request_t req
;
1197 char *server_name
= jack_default_server_name ();
1200 snprintf (req
.name
, sizeof (req
.name
), "%s", client_name
);
1202 if ((fd
= server_connect (server_name
)) < 0) {
1206 if (write (fd
, &req
, sizeof (req
)) != sizeof(req
)) {
1207 jack_error ("cannot deliver ClientUnload request to JACK "
1211 /* no response to this request */
1218 jack_recompute_total_latencies (jack_client_t
* client
)
1220 jack_request_t request
;
1222 request
.type
= RecomputeTotalLatencies
;
1223 return jack_client_deliver_request (client
, &request
);
1227 jack_recompute_total_latency (jack_client_t
* client
, jack_port_t
* port
)
1229 jack_request_t request
;
1231 request
.type
= RecomputeTotalLatency
;
1232 request
.x
.port_info
.port_id
= port
->shared
->id
;
1233 return jack_client_deliver_request (client
, &request
);
1237 jack_set_freewheel (jack_client_t
* client
, int onoff
)
1239 jack_request_t request
;
1241 request
.type
= onoff
? FreeWheel
: StopFreeWheel
;
1242 return jack_client_deliver_request (client
, &request
);
1246 jack_start_freewheel (jack_client_t
* client
)
1248 jack_client_control_t
*control
= client
->control
;
1250 if (client
->engine
->real_time
) {
1251 #if JACK_USE_MACH_THREADS
1252 jack_drop_real_time_scheduling (client
->process_thread
);
1254 jack_drop_real_time_scheduling (client
->thread
);
1258 if (control
->freewheel_cb_cbset
) {
1259 client
->freewheel_cb (1, client
->freewheel_arg
);
1264 jack_stop_freewheel (jack_client_t
* client
)
1266 jack_client_control_t
*control
= client
->control
;
1268 if (client
->engine
->real_time
) {
1269 #if JACK_USE_MACH_THREADS
1270 jack_acquire_real_time_scheduling (client
->process_thread
,
1271 client
->engine
->client_priority
);
1273 jack_acquire_real_time_scheduling (client
->thread
,
1274 client
->engine
->client_priority
);
1278 if (control
->freewheel_cb_cbset
) {
1279 client
->freewheel_cb (0, client
->freewheel_arg
);
1284 jack_client_thread_suicide (jack_client_t
* client
)
1286 if (client
->on_shutdown
) {
1287 jack_error ("zombified - calling shutdown handler");
1288 client
->on_shutdown (client
->on_shutdown_arg
);
1290 jack_error ("jack_client_thread zombified - exiting from JACK");
1291 jack_client_close_aux (client
);
1292 /* Need a fix : possibly make client crash if
1293 * zombified without shutdown handler
1302 jack_client_process_events (jack_client_t
* client
)
1306 jack_client_control_t
*control
= client
->control
;
1310 DEBUG ("process events");
1312 if (client
->pollfd
[EVENT_POLL_INDEX
].revents
& POLLIN
) {
1314 DEBUG ("client receives an event, "
1315 "now reading on event fd");
1317 /* server has sent us an event. process the
1318 * event and reply */
1320 if (read (client
->event_fd
, &event
, sizeof (event
))
1321 != sizeof (event
)) {
1322 jack_error ("cannot read server event (%s)",
1329 switch (event
.type
) {
1330 case PortRegistered
:
1331 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
1333 if (port
->shared
->id
== event
.x
.port_id
) { // Found port, update port type
1334 port
->type_info
= &client
->engine
->port_types
[port
->shared
->ptype_id
];
1337 if (control
->port_register_cbset
) {
1338 client
->port_register
1339 (event
.x
.port_id
, TRUE
,
1340 client
->port_register_arg
);
1344 case PortUnregistered
:
1345 if (control
->port_register_cbset
) {
1346 client
->port_register
1347 (event
.x
.port_id
, FALSE
,
1348 client
->port_register_arg
);
1352 case ClientRegistered
:
1353 if (control
->client_register_cbset
) {
1354 client
->client_register
1355 (event
.x
.name
, TRUE
,
1356 client
->client_register_arg
);
1360 case ClientUnregistered
:
1361 if (control
->client_register_cbset
) {
1362 client
->client_register
1363 (event
.x
.name
, FALSE
,
1364 client
->client_register_arg
);
1368 case GraphReordered
:
1369 status
= jack_handle_reorder (client
, &event
);
1373 case PortDisconnected
:
1374 status
= jack_client_handle_port_connection
1378 case BufferSizeChange
:
1379 jack_client_invalidate_port_buffers (client
);
1380 if (control
->bufsize_cbset
) {
1381 status
= client
->bufsize
1383 client
->bufsize_arg
);
1387 case SampleRateChange
:
1388 if (control
->srate_cbset
) {
1389 status
= client
->srate
1396 if (control
->xrun_cbset
) {
1397 status
= client
->xrun
1402 case AttachPortSegment
:
1403 jack_attach_port_segment (client
, event
.y
.ptid
);
1406 case StartFreewheel
:
1407 jack_start_freewheel (client
);
1411 jack_stop_freewheel (client
);
1415 DEBUG ("client has dealt with the event, writing "
1416 "response on event fd");
1418 if (write (client
->event_fd
, &status
, sizeof (status
))
1419 != sizeof (status
)) {
1420 jack_error ("cannot send event response to "
1421 "engine (%s)", strerror (errno
));
1430 jack_client_core_wait (jack_client_t
* client
)
1432 jack_client_control_t
*control
= client
->control
;
1434 DEBUG ("client polling on %s", client
->pollmax
== 2 ?
1435 "event_fd and graph_wait_fd..." :
1439 if (poll (client
->pollfd
, client
->pollmax
, 1000) < 0) {
1440 if (errno
== EINTR
) {
1443 jack_error ("poll failed in client (%s)",
1448 pthread_testcancel();
1450 #ifndef JACK_USE_MACH_THREADS
1452 /* get an accurate timestamp on waking from poll for a
1456 if (client
->graph_wait_fd
>= 0
1457 && client
->pollfd
[WAIT_POLL_INDEX
].revents
& POLLIN
) {
1458 control
->awake_at
= jack_get_microseconds();
1461 DEBUG ("pfd[EVENT].revents = 0x%x pfd[WAIT].revents = 0x%x",
1462 client
->pollfd
[EVENT_POLL_INDEX
].revents
,
1463 client
->pollfd
[WAIT_POLL_INDEX
].revents
);
1465 if (client
->graph_wait_fd
>= 0 &&
1466 (client
->pollfd
[WAIT_POLL_INDEX
].revents
& ~POLLIN
)) {
1468 /* our upstream "wait" connection
1469 closed, which either means that
1470 an intermediate client exited, or
1471 jackd exited, or jackd zombified
1474 we can discover the zombification
1475 via client->control->dead, but
1476 the other two possibilities are
1477 impossible to identify just from
1478 this situation. so we have to
1479 check what we are connected to,
1480 and act accordingly.
1483 if (client
->upstream_is_jackd
) {
1487 DEBUG ("WE PUNT\n");
1488 /* don't poll on the wait fd
1489 * again until we get a
1490 * GraphReordered event.
1493 client
->graph_wait_fd
= -1;
1494 client
->pollmax
= 1;
1499 if (jack_client_process_events (client
)) {
1500 DEBUG ("event processing failed\n");
1504 if (client
->graph_wait_fd
>= 0 &&
1505 (client
->pollfd
[WAIT_POLL_INDEX
].revents
& POLLIN
)) {
1506 DEBUG ("time to run process()\n");
1511 if (client
->control
->dead
|| client
->pollfd
[EVENT_POLL_INDEX
].revents
& ~POLLIN
) {
1512 DEBUG ("client appears dead or event pollfd has error status\n");
1520 jack_wake_next_client (jack_client_t
* client
)
1522 struct pollfd pfds
[1];
1526 if (write (client
->graph_next_fd
, &c
, sizeof (c
))
1528 DEBUG("cannot write byte to fd %d", client
->graph_next_fd
);
1529 jack_error ("cannot continue execution of the "
1530 "processing graph (%s)",
1535 DEBUG ("client sent message to next stage by %" PRIu64
"",
1536 jack_get_microseconds());
1538 DEBUG("reading cleanup byte from pipe %d\n", client
->graph_wait_fd
);
1540 /* "upstream client went away? readability is checked in
1541 * jack_client_core_wait(), but that's almost a whole cycle
1542 * before we get here.
1545 if (client
->graph_wait_fd
>= 0) {
1546 pfds
[0].fd
= client
->graph_wait_fd
;
1547 pfds
[0].events
= POLLIN
;
1549 /* 0 timeout, don't actually wait */
1550 pret
= poll(pfds
, 1, 0);
1553 if (pret
> 0 && (pfds
[0].revents
& POLLIN
)) {
1554 if (read (client
->graph_wait_fd
, &c
, sizeof (c
))
1556 jack_error ("cannot complete execution of the "
1557 "processing graph (%s)", strerror(errno
));
1561 DEBUG("cleanup byte from pipe %d not available?\n",
1562 client
->graph_wait_fd
);
1568 static jack_nframes_t
1569 jack_thread_first_wait (jack_client_t
* client
)
1571 if (jack_client_core_wait (client
)) {
1574 return client
->control
->nframes
;
1578 jack_thread_wait (jack_client_t
* client
, int status
)
1580 client
->control
->last_status
= status
;
1582 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1584 /* housekeeping/cleanup after data processing */
1586 if (status
== 0 && client
->control
->timebase_cb_cbset
) {
1587 jack_call_timebase_master (client
);
1590 /* end preemption checking */
1591 CHECK_PREEMPTION (client
->engine
, FALSE
);
1593 client
->control
->finished_at
= jack_get_microseconds();
1595 /* wake the next client in the chain (could be the server),
1596 and check if we were killed during the process
1600 if (jack_wake_next_client (client
)) {
1601 DEBUG("client cannot wake next, or is dead\n");
1605 if (status
|| client
->control
->dead
|| !client
->engine
->engine_ok
) {
1609 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1611 if (jack_client_core_wait (client
)) {
1615 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1617 /* Time to do data processing */
1619 client
->control
->state
= Running
;
1621 /* begin preemption checking */
1622 CHECK_PREEMPTION (client
->engine
, TRUE
);
1624 if (client
->control
->sync_cb_cbset
)
1625 jack_call_sync_client (client
);
1627 return client
->control
->nframes
;
1630 jack_nframes_t
jack_cycle_wait (jack_client_t
* client
)
1632 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1634 if (jack_client_core_wait (client
)) {
1638 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1640 /* Time to do data processing */
1642 client
->control
->state
= Running
;
1644 /* begin preemption checking */
1645 CHECK_PREEMPTION (client
->engine
, TRUE
);
1647 if (client
->control
->sync_cb_cbset
)
1648 jack_call_sync_client (client
);
1650 return client
->control
->nframes
;
1653 void jack_cycle_signal(jack_client_t
* client
, int status
)
1655 client
->control
->last_status
= status
;
1657 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1659 /* housekeeping/cleanup after data processing */
1661 if (status
== 0 && client
->control
->timebase_cb_cbset
) {
1662 jack_call_timebase_master (client
);
1665 /* end preemption checking */
1666 CHECK_PREEMPTION (client
->engine
, FALSE
);
1668 client
->control
->finished_at
= jack_get_microseconds();
1670 /* wake the next client in the chain (could be the server),
1671 and check if we were killed during the process
1675 if (jack_wake_next_client (client
)) {
1676 DEBUG("client cannot wake next, or is dead\n");
1677 jack_client_thread_suicide (client
);
1681 if (status
|| client
->control
->dead
|| !client
->engine
->engine_ok
) {
1682 jack_client_thread_suicide (client
);
1688 jack_client_thread_aux (void *arg
)
1690 jack_client_t
*client
= (jack_client_t
*) arg
;
1691 jack_client_control_t
*control
= client
->control
;
1693 pthread_mutex_lock (&client_lock
);
1694 client
->thread_ok
= TRUE
;
1695 client
->thread_id
= pthread_self();
1696 pthread_cond_signal (&client_ready
);
1697 pthread_mutex_unlock (&client_lock
);
1699 control
->pid
= getpid();
1700 control
->pgrp
= getpgrp();
1702 DEBUG ("client thread is now running");
1704 if (control
->thread_init_cbset
) {
1705 DEBUG ("calling client thread init callback");
1706 client
->thread_init (client
->thread_init_arg
);
1709 /* wait for first wakeup from server */
1711 if (jack_thread_first_wait (client
) == control
->nframes
) {
1713 /* now run till we're done */
1715 if (control
->process_cbset
) {
1717 /* run process callback, then wait... ad-infinitum */
1720 DEBUG("client calls process()");
1721 int status
= (client
->process (control
->nframes
,
1722 client
->process_arg
) ==
1724 control
->state
= Finished
;
1725 DEBUG("client leaves process(), re-enters wait");
1726 if (!jack_thread_wait (client
, status
)) {
1729 DEBUG("client done with wait");
1733 /* no process handling but still need to process events */
1734 while (jack_thread_wait (client
, 0) == control
->nframes
)
1739 jack_client_thread_suicide (client
);
1743 jack_client_thread (void *arg
)
1745 jack_client_t
*client
= (jack_client_t
*) arg
;
1746 jack_client_control_t
*control
= client
->control
;
1748 if (client
->control
->thread_cb_cbset
) {
1750 pthread_mutex_lock (&client_lock
);
1751 client
->thread_ok
= TRUE
;
1752 client
->thread_id
= pthread_self();
1753 pthread_cond_signal (&client_ready
);
1754 pthread_mutex_unlock (&client_lock
);
1756 control
->pid
= getpid();
1757 control
->pgrp
= getpgrp();
1759 client
->thread_cb(client
->thread_cb_arg
);
1760 jack_client_thread_suicide(client
);
1762 jack_client_thread_aux(arg
);
1769 #ifdef JACK_USE_MACH_THREADS
1770 /* real-time thread : separated from the normal client thread, it will
1771 * communicate with the server using fast mach RPC mechanism */
1774 jack_client_process_thread (void *arg
)
1776 jack_client_t
*client
= (jack_client_t
*) arg
;
1777 jack_client_control_t
*control
= client
->control
;
1780 if (client
->control
->thread_init
) {
1781 /* this means that the init callback will be called twice -taybin*/
1782 DEBUG ("calling client thread init callback");
1783 client
->control
->thread_init (client
->control
->thread_init_arg
);
1786 client
->control
->pid
= getpid();
1787 DEBUG ("client process thread is now running");
1789 client
->rt_thread_ok
= TRUE
;
1793 if (jack_client_suspend(client
) < 0) {
1794 jack_error ("jack_client_process_thread :resume error");
1798 control
->awake_at
= jack_get_microseconds();
1800 DEBUG ("client resumed");
1802 control
->state
= Running
;
1804 if (control
->sync_cb
)
1805 jack_call_sync_client (client
);
1807 if (control
->process
) {
1808 if (control
->process (control
->nframes
,
1809 control
->process_arg
) == 0) {
1810 control
->state
= Finished
;
1813 control
->state
= Finished
;
1816 if (control
->timebase_cb
)
1817 jack_call_timebase_master (client
);
1819 control
->finished_at
= jack_get_microseconds();
1821 DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
1822 control
->finished_at
,
1823 ((float)(control
->finished_at
- control
->awake_at
)));
1825 /* check if we were killed during the process cycle
1828 if (client
->control
->dead
) {
1829 jack_error ("jack_client_process_thread: "
1830 "client->control->dead");
1834 DEBUG("process cycle fully complete\n");
1838 return (void *) ((intptr_t)err
);
1842 jack_error ("jack_client_process_thread : zombified");
1844 client
->rt_thread_ok
= FALSE
;
1846 if (client
->on_shutdown
) {
1847 jack_error ("zombified - calling shutdown handler");
1848 client
->on_shutdown (client
->on_shutdown_arg
);
1850 jack_error ("jack_client_process_thread zombified - exiting from JACK");
1851 /* Need a fix : possibly make client crash if
1852 * zombified without shutdown handler */
1853 jack_client_close_aux (client
);
1860 #endif /* JACK_USE_MACH_THREADS */
1863 jack_start_thread (jack_client_t
*client
)
1865 if (client
->engine
->real_time
) {
1868 if (client
->engine
->do_mlock
1869 && (mlockall (MCL_CURRENT
| MCL_FUTURE
) != 0)) {
1870 jack_error ("cannot lock down memory for RT thread "
1871 "(%s)", strerror (errno
));
1875 #endif /* ENSURE_MLOCK */
1878 if (client
->engine
->do_munlock
) {
1881 #endif /* USE_MLOCK */
1884 #ifdef JACK_USE_MACH_THREADS
1885 /* Stephane Letz : letz@grame.fr
1886 On MacOSX, the normal thread does not need to be real-time.
1888 if (jack_client_create_thread (client
,
1890 client
->engine
->client_priority
,
1892 jack_client_thread
, client
)) {
1896 if (jack_client_create_thread (client
,
1898 client
->engine
->client_priority
,
1899 client
->engine
->real_time
,
1900 jack_client_thread
, client
)) {
1906 #ifdef JACK_USE_MACH_THREADS
1908 /* a secondary thread that runs the process callback and uses
1909 ultra-fast Mach primitives for inter-thread signalling.
1911 XXX in a properly structured JACK, there would be no
1912 need for this, because we would have client wake up
1913 methods that encapsulated the underlying mechanism
1918 if (jack_client_create_thread(client
,
1919 &client
->process_thread
,
1920 client
->engine
->client_priority
,
1921 client
->engine
->real_time
,
1922 jack_client_process_thread
, client
)) {
1925 #endif /* JACK_USE_MACH_THREADS */
1931 jack_activate (jack_client_t
*client
)
1935 /* we need to scribble on our stack to ensure that its memory
1936 * pages are actually mapped (more important for mlockall(2)
1937 * usage in jack_start_thread())
1940 char buf
[JACK_THREAD_STACK_TOUCH
];
1943 for (i
= 0; i
< JACK_THREAD_STACK_TOUCH
; i
++) {
1944 buf
[i
] = (char) (i
& 0xff);
1947 if (client
->control
->type
== ClientInternal
||
1948 client
->control
->type
== ClientDriver
) {
1952 /* get the pid of the client process to pass it to engine */
1954 client
->control
->pid
= getpid ();
1956 #ifdef USE_CAPABILITIES
1958 if (client
->engine
->has_capabilities
!= 0 &&
1959 client
->control
->pid
!= 0 && client
->engine
->real_time
!= 0) {
1961 /* we need to ask the engine for realtime capabilities
1962 before trying to start the realtime thread
1965 req
.type
= SetClientCapabilities
;
1966 req
.x
.client_id
= client
->control
->id
;
1967 req
.x
.cap_pid
= client
->control
->pid
;
1969 jack_client_deliver_request (client
, &req
);
1973 /* what to do? engine is running realtime, it
1974 is using capabilities and has them
1975 (otherwise we would not get an error
1976 return) but for some reason it could not
1977 give the client the required capabilities.
1978 For now, leave the client so that it
1979 still runs, albeit non-realtime.
1982 jack_error ("could not receive realtime capabilities, "
1983 "client will run non-realtime");
1986 #endif /* USE_CAPABILITIES */
1988 if (client
->first_active
) {
1990 pthread_mutex_init (&client_lock
, NULL
);
1991 pthread_cond_init (&client_ready
, NULL
);
1993 pthread_mutex_lock (&client_lock
);
1995 if (jack_start_thread (client
)) {
1996 pthread_mutex_unlock (&client_lock
);
2000 pthread_cond_wait (&client_ready
, &client_lock
);
2001 pthread_mutex_unlock (&client_lock
);
2003 if (!client
->thread_ok
) {
2004 jack_error ("could not start client thread");
2008 client
->first_active
= FALSE
;
2013 req
.type
= ActivateClient
;
2014 req
.x
.client_id
= client
->control
->id
;
2016 return jack_client_deliver_request (client
, &req
);
2020 jack_deactivate_aux (jack_client_t
*client
)
2023 int rc
= ESRCH
; /* already shut down */
2025 if (client
&& client
->control
) { /* not shut down? */
2027 if (client
->control
->active
) { /* still active? */
2028 req
.type
= DeactivateClient
;
2029 req
.x
.client_id
= client
->control
->id
;
2030 rc
= jack_client_deliver_request (client
, &req
);
2037 jack_deactivate (jack_client_t
*client
)
2039 return jack_deactivate_aux(client
);
2043 jack_client_close_aux (jack_client_t
*client
)
2049 rc
= jack_deactivate_aux (client
);
2050 if (rc
== ESRCH
) { /* already shut down? */
2054 if (client
->control
->type
== ClientExternal
) {
2056 #if JACK_USE_MACH_THREADS
2057 if (client
->rt_thread_ok
) {
2058 // MacOSX pthread_cancel not implemented in
2060 mach_port_t machThread
=
2061 pthread_mach_thread_np (client
->process_thread
);
2062 thread_terminate (machThread
);
2066 /* stop the thread that communicates with the jack
2067 * server, only if it was actually running
2070 if (client
->thread_ok
){
2071 pthread_cancel (client
->thread
);
2072 pthread_join (client
->thread
, &status
);
2075 if (client
->control
) {
2076 jack_release_shm (&client
->control_shm
);
2077 client
->control
= NULL
;
2079 if (client
->engine
) {
2080 jack_release_shm (&client
->engine_shm
);
2081 client
->engine
= NULL
;
2084 if (client
->port_segment
) {
2085 jack_port_type_id_t ptid
;
2086 for (ptid
= 0; ptid
< client
->n_port_types
; ++ptid
) {
2087 jack_release_shm (&client
->port_segment
[ptid
]);
2089 free (client
->port_segment
);
2090 client
->port_segment
= NULL
;
2093 #ifndef JACK_USE_MACH_THREADS
2094 if (client
->graph_wait_fd
>= 0) {
2095 close (client
->graph_wait_fd
);
2098 if (client
->graph_next_fd
>= 0) {
2099 close (client
->graph_next_fd
);
2103 close (client
->event_fd
);
2105 if (shutdown (client
->request_fd
, SHUT_RDWR
)) {
2106 jack_error ("could not shutdown client request socket");
2109 close (client
->request_fd
);
2113 for (node
= client
->ports
; node
; node
= jack_slist_next (node
)) {
2116 jack_slist_free (client
->ports
);
2117 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
2120 jack_slist_free (client
->ports_ext
);
2121 jack_client_free (client
);
2122 jack_messagebuffer_exit ();
2128 jack_client_close (jack_client_t
*client
)
2130 return jack_client_close_aux(client
);
2134 jack_is_realtime (jack_client_t
*client
)
2136 return client
->engine
->real_time
;
2140 jack_get_buffer_size (jack_client_t
*client
)
2142 return client
->engine
->buffer_size
;
2146 jack_set_buffer_size (jack_client_t
*client
, jack_nframes_t nframes
)
2148 #ifdef DO_BUFFER_RESIZE
2151 req
.type
= SetBufferSize
;
2152 req
.x
.nframes
= nframes
;
2154 return jack_client_deliver_request (client
, &req
);
2158 #endif /* DO_BUFFER_RESIZE */
2162 jack_connect (jack_client_t
*client
, const char *source_port
,
2163 const char *destination_port
)
2167 req
.type
= ConnectPorts
;
2169 snprintf (req
.x
.connect
.source_port
,
2170 sizeof (req
.x
.connect
.source_port
), "%s", source_port
);
2171 snprintf (req
.x
.connect
.destination_port
,
2172 sizeof (req
.x
.connect
.destination_port
),
2173 "%s", destination_port
);
2175 return jack_client_deliver_request (client
, &req
);
2179 jack_port_disconnect (jack_client_t
*client
, jack_port_t
*port
)
2183 pthread_mutex_lock (&port
->connection_lock
);
2185 if (port
->connections
== NULL
) {
2186 pthread_mutex_unlock (&port
->connection_lock
);
2190 pthread_mutex_unlock (&port
->connection_lock
);
2192 req
.type
= DisconnectPort
;
2193 req
.x
.port_info
.port_id
= port
->shared
->id
;
2195 return jack_client_deliver_request (client
, &req
);
2199 jack_disconnect (jack_client_t
*client
, const char *source_port
,
2200 const char *destination_port
)
2204 req
.type
= DisconnectPorts
;
2206 snprintf (req
.x
.connect
.source_port
,
2207 sizeof (req
.x
.connect
.source_port
), "%s", source_port
);
2208 snprintf (req
.x
.connect
.destination_port
,
2209 sizeof (req
.x
.connect
.destination_port
),
2210 "%s", destination_port
);
2212 return jack_client_deliver_request (client
, &req
);
2216 jack_set_error_function (void (*func
) (const char *))
2218 jack_error_callback
= func
;
2222 jack_set_info_function (void (*func
) (const char *))
2224 jack_info_callback
= func
;
2228 jack_set_graph_order_callback (jack_client_t
*client
,
2229 JackGraphOrderCallback callback
, void *arg
)
2231 if (client
->control
->active
) {
2232 jack_error ("You cannot set callbacks on an active client.");
2235 client
->graph_order
= callback
;
2236 client
->graph_order_arg
= arg
;
2237 client
->control
->graph_order_cbset
= (callback
!= NULL
);
2241 int jack_set_xrun_callback (jack_client_t
*client
,
2242 JackXRunCallback callback
, void *arg
)
2244 if (client
->control
->active
) {
2245 jack_error ("You cannot set callbacks on an active client.");
2249 client
->xrun
= callback
;
2250 client
->xrun_arg
= arg
;
2251 client
->control
->xrun_cbset
= (callback
!= NULL
);
2256 jack_set_process_callback (jack_client_t
*client
,
2257 JackProcessCallback callback
, void *arg
)
2260 if (client
->control
->active
) {
2261 jack_error ("You cannot set callbacks on an active client.");
2265 if (client
->control
->thread_cb_cbset
) {
2266 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
2270 client
->process_arg
= arg
;
2271 client
->process
= callback
;
2272 client
->control
->process_cbset
= (callback
!= NULL
);
2277 jack_set_thread_init_callback (jack_client_t
*client
,
2278 JackThreadInitCallback callback
, void *arg
)
2281 if (client
->control
->active
) {
2282 jack_error ("You cannot set callbacks on an active client.");
2285 client
->thread_init_arg
= arg
;
2286 client
->thread_init
= callback
;
2287 client
->control
->thread_init_cbset
= (callback
!= NULL
);
2292 jack_set_freewheel_callback (jack_client_t
*client
,
2293 JackFreewheelCallback callback
, void *arg
)
2295 if (client
->control
->active
) {
2296 jack_error ("You cannot set callbacks on an active client.");
2299 client
->freewheel_arg
= arg
;
2300 client
->freewheel_cb
= callback
;
2301 client
->control
->freewheel_cb_cbset
= (callback
!= NULL
);
2306 jack_set_buffer_size_callback (jack_client_t
*client
,
2307 JackBufferSizeCallback callback
, void *arg
)
2309 client
->bufsize_arg
= arg
;
2310 client
->bufsize
= callback
;
2311 client
->control
->bufsize_cbset
= (callback
!= NULL
);
2316 jack_set_port_registration_callback(jack_client_t
*client
,
2317 JackPortRegistrationCallback callback
,
2320 if (client
->control
->active
) {
2321 jack_error ("You cannot set callbacks on an active client.");
2324 client
->port_register_arg
= arg
;
2325 client
->port_register
= callback
;
2326 client
->control
->port_register_cbset
= (callback
!= NULL
);
2331 jack_set_port_connect_callback(jack_client_t
*client
,
2332 JackPortConnectCallback callback
,
2335 if (client
->control
->active
) {
2336 jack_error ("You cannot set callbacks on an active client.");
2339 client
->port_connect_arg
= arg
;
2340 client
->port_connect
= callback
;
2341 client
->control
->port_connect_cbset
= (callback
!= NULL
);
2346 jack_set_client_registration_callback(jack_client_t
*client
,
2347 JackClientRegistrationCallback callback
,
2350 if (client
->control
->active
) {
2351 jack_error ("You cannot set callbacks on an active client.");
2354 client
->client_register_arg
= arg
;
2355 client
->client_register
= callback
;
2356 client
->control
->client_register_cbset
= (callback
!= NULL
);
2361 jack_set_process_thread(jack_client_t
* client
, JackThreadCallback callback
, void *arg
)
2363 if (client
->control
->active
) {
2364 jack_error ("You cannot set callbacks on an active client.");
2368 if (client
->control
->process_cbset
) {
2369 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
2373 client
->thread_cb_arg
= arg
;
2374 client
->thread_cb
= callback
;
2375 client
->control
->thread_cb_cbset
= (callback
!= NULL
);
2380 jack_get_process_done_fd (jack_client_t
*client
)
2382 return client
->graph_next_fd
;
2386 jack_on_shutdown (jack_client_t
*client
, void (*function
)(void *arg
), void *arg
)
2388 client
->on_shutdown
= function
;
2389 client
->on_shutdown_arg
= arg
;
2393 jack_get_ports (jack_client_t
*client
,
2394 const char *port_name_pattern
,
2395 const char *type_name_pattern
,
2396 unsigned long flags
)
2398 jack_control_t
*engine
;
2399 const char **matching_ports
;
2400 unsigned long match_cnt
;
2401 jack_port_shared_t
*psp
;
2407 engine
= client
->engine
;
2409 if (port_name_pattern
&& port_name_pattern
[0]) {
2410 regcomp (&port_regex
, port_name_pattern
,
2411 REG_EXTENDED
|REG_NOSUB
);
2413 if (type_name_pattern
&& type_name_pattern
[0]) {
2414 regcomp (&type_regex
, type_name_pattern
,
2415 REG_EXTENDED
|REG_NOSUB
);
2418 psp
= engine
->ports
;
2421 matching_ports
= (const char **)
2422 malloc (sizeof (char *) * engine
->port_max
);
2424 for (i
= 0; i
< engine
->port_max
; i
++) {
2427 if (!psp
[i
].in_use
) {
2432 if ((psp
[i
].flags
& flags
) != flags
) {
2437 if (matching
&& port_name_pattern
&& port_name_pattern
[0]) {
2438 if (regexec (&port_regex
, psp
[i
].name
, 0, NULL
, 0)) {
2443 if (matching
&& type_name_pattern
&& type_name_pattern
[0]) {
2444 jack_port_type_id_t ptid
= psp
[i
].ptype_id
;
2445 if (regexec (&type_regex
,
2446 engine
->port_types
[ptid
].type_name
,
2453 matching_ports
[match_cnt
++] = psp
[i
].name
;
2456 if (port_name_pattern
&& port_name_pattern
[0]) {
2457 regfree (&port_regex
);
2459 if (type_name_pattern
&& type_name_pattern
[0]) {
2460 regfree (&type_regex
);
2463 matching_ports
[match_cnt
] = 0;
2465 if (match_cnt
== 0) {
2466 free (matching_ports
);
2470 return matching_ports
;
2474 jack_cpu_load (jack_client_t
*client
)
2476 return client
->engine
->cpu_load
;
2480 jack_get_xrun_delayed_usecs (jack_client_t
*client
)
2482 return client
->engine
->xrun_delayed_usecs
;
2486 jack_get_max_delayed_usecs (jack_client_t
*client
)
2488 return client
->engine
->max_delayed_usecs
;
2492 jack_reset_max_delayed_usecs (jack_client_t
*client
)
2494 client
->engine
->max_delayed_usecs
= 0.0f
;
2498 jack_client_thread_id (jack_client_t
*client
)
2500 return client
->thread_id
;
2504 jack_client_name_size(void)
2506 return JACK_CLIENT_NAME_SIZE
;
2510 jack_port_name_size(void)
2512 return JACK_PORT_NAME_SIZE
;
2516 jack_port_type_size(void)
2518 return JACK_PORT_TYPE_SIZE
;