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
->on_info_shutdown
= NULL
;
304 client
->n_port_types
= 0;
305 client
->port_segment
= NULL
;
309 #endif /* USE_DYNSIMD */
319 jack_client_t
*client
;
321 client
= (jack_client_t
*) malloc (sizeof (jack_client_t
));
322 client
->pollfd
= (struct pollfd
*) malloc (sizeof (struct pollfd
) * 2);
324 client
->request_fd
= -1;
325 client
->event_fd
= -1;
326 client
->upstream_is_jackd
= 0;
327 client
->graph_wait_fd
= -1;
328 client
->graph_next_fd
= -1;
329 client
->ports
= NULL
;
330 client
->ports_ext
= NULL
;
331 client
->engine
= NULL
;
332 client
->control
= NULL
;
333 client
->thread_ok
= FALSE
;
334 client
->first_active
= TRUE
;
335 client
->on_shutdown
= NULL
;
336 client
->on_info_shutdown
= NULL
;
337 client
->n_port_types
= 0;
338 client
->port_segment
= NULL
;
342 #endif /* USE_DYNSIMD */
350 * Build the jack_client_t structure for an internal client.
353 jack_client_alloc_internal (jack_client_control_t
*cc
, jack_engine_t
* engine
)
355 jack_client_t
* client
;
357 client
= jack_client_alloc ();
359 client
->control
= cc
;
360 client
->engine
= engine
->control
;
362 client
->n_port_types
= client
->engine
->n_port_types
;
363 client
->port_segment
= &engine
->port_segment
[0];
369 jack_client_free (jack_client_t
*client
)
371 if (client
->pollfd
) {
372 free (client
->pollfd
);
379 jack_client_invalidate_port_buffers (jack_client_t
*client
)
384 /* This releases all local memory owned by input ports
385 and sets the buffer pointer to NULL. This will cause
386 jack_port_get_buffer() to reallocate space for the
387 buffer on the next call (if there is one).
390 for (node
= client
->ports
; node
; node
= jack_slist_next (node
)) {
391 port
= (jack_port_t
*) node
->data
;
393 if (port
->shared
->flags
& JackPortIsInput
) {
394 if (port
->mix_buffer
) {
395 jack_pool_release (port
->mix_buffer
);
396 port
->mix_buffer
= NULL
;
403 jack_client_handle_port_connection (jack_client_t
*client
, jack_event_t
*event
)
405 jack_port_t
*control_port
;
406 jack_port_t
*other
= 0;
408 int need_free
= FALSE
;
410 if (client
->engine
->ports
[event
->x
.self_id
].client_id
== client
->control
->id
||
411 client
->engine
->ports
[event
->y
.other_id
].client_id
== client
->control
->id
) {
413 /* its one of ours */
415 switch (event
->type
) {
417 other
= jack_port_new (client
, event
->y
.other_id
,
419 /* jack_port_by_id_int() always returns an internal
420 * port that does not need to be deallocated
422 control_port
= jack_port_by_id_int (client
, event
->x
.self_id
,
424 pthread_mutex_lock (&control_port
->connection_lock
);
425 control_port
->connections
=
426 jack_slist_prepend (control_port
->connections
,
428 pthread_mutex_unlock (&control_port
->connection_lock
);
431 case PortDisconnected
:
432 /* jack_port_by_id_int() always returns an internal
433 * port that does not need to be deallocated
435 control_port
= jack_port_by_id_int (client
, event
->x
.self_id
,
437 pthread_mutex_lock (&control_port
->connection_lock
);
439 for (node
= control_port
->connections
; node
;
440 node
= jack_slist_next (node
)) {
442 other
= (jack_port_t
*) node
->data
;
444 if (other
->shared
->id
== event
->y
.other_id
) {
445 control_port
->connections
=
446 jack_slist_remove_link (
447 control_port
->connections
,
449 jack_slist_free_1 (node
);
455 pthread_mutex_unlock (&control_port
->connection_lock
);
464 if (client
->control
->port_connect_cbset
) {
465 client
->port_connect (event
->x
.self_id
, event
->y
.other_id
,
466 (event
->type
== PortConnected
? 1 : 0),
467 client
->port_connect_arg
);
473 #if JACK_USE_MACH_THREADS
476 jack_handle_reorder (jack_client_t
*client
, jack_event_t
*event
)
480 /* If the client registered its own callback for graph order events,
484 if (client
->control
->graph_order_cbset
) {
485 client
->graph_order (client
->graph_order_arg
);
494 jack_handle_reorder (jack_client_t
*client
, jack_event_t
*event
)
496 char path
[PATH_MAX
+1];
498 DEBUG ("graph reorder\n");
500 if (client
->graph_wait_fd
>= 0) {
501 DEBUG ("closing graph_wait_fd==%d", client
->graph_wait_fd
);
502 close (client
->graph_wait_fd
);
503 client
->graph_wait_fd
= -1;
506 if (client
->graph_next_fd
>= 0) {
507 DEBUG ("closing graph_next_fd==%d", client
->graph_next_fd
);
508 close (client
->graph_next_fd
);
509 client
->graph_next_fd
= -1;
512 sprintf (path
, "%s-%" PRIu32
, client
->fifo_prefix
, event
->x
.n
);
514 if ((client
->graph_wait_fd
= open (path
, O_RDONLY
|O_NONBLOCK
)) < 0) {
515 jack_error ("cannot open specified fifo [%s] for reading (%s)",
516 path
, strerror (errno
));
519 DEBUG ("opened new graph_wait_fd %d (%s)", client
->graph_wait_fd
, path
);
521 sprintf (path
, "%s-%" PRIu32
, client
->fifo_prefix
, event
->x
.n
+1);
523 if ((client
->graph_next_fd
= open (path
, O_WRONLY
|O_NONBLOCK
)) < 0) {
524 jack_error ("cannot open specified fifo [%s] for writing (%s)",
525 path
, strerror (errno
));
529 client
->upstream_is_jackd
= event
->y
.n
;
532 DEBUG ("opened new graph_next_fd %d (%s) (upstream is jackd? %d)",
533 client
->graph_next_fd
, path
,
534 client
->upstream_is_jackd
);
536 /* If the client registered its own callback for graph order events,
540 if (client
->control
->graph_order_cbset
) {
541 client
->graph_order (client
->graph_order_arg
);
550 server_connect (const char *server_name
)
553 struct sockaddr_un addr
;
556 char server_dir
[PATH_MAX
+1] = "";
558 if ((fd
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0) {
559 jack_error ("cannot create client socket (%s)",
564 //JOQ: temporary debug message
565 //jack_info ("DEBUG: connecting to `%s' server", server_name);
567 addr
.sun_family
= AF_UNIX
;
568 snprintf (addr
.sun_path
, sizeof (addr
.sun_path
) - 1, "%s/jack_%d",
569 jack_server_dir (server_name
, server_dir
) , which
);
571 if (connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
580 server_event_connect (jack_client_t
*client
, const char *server_name
)
583 struct sockaddr_un addr
;
584 jack_client_connect_ack_request_t req
;
585 jack_client_connect_ack_result_t res
;
587 char server_dir
[PATH_MAX
+1] = "";
589 if ((fd
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0) {
590 jack_error ("cannot create client event socket (%s)",
595 addr
.sun_family
= AF_UNIX
;
596 snprintf (addr
.sun_path
, sizeof (addr
.sun_path
) - 1, "%s/jack_ack_0",
597 jack_server_dir (server_name
,server_dir
));
599 if (connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
600 jack_error ("cannot connect to jack server for events",
606 req
.client_id
= client
->control
->id
;
608 if (write (fd
, &req
, sizeof (req
)) != sizeof (req
)) {
609 jack_error ("cannot write event connect request to server (%s)",
615 if (read (fd
, &res
, sizeof (res
)) != sizeof (res
)) {
616 jack_error ("cannot read event connect result from server (%s)",
622 if (res
.status
!= 0) {
623 jack_error ("cannot connect to server for event stream (%s)",
632 /* Exec the JACK server in this process. Does not return. */
634 _start_server (const char *server_name
)
648 snprintf(filename
, 255, "%s/.jackdrc", getenv("HOME"));
649 fp
= fopen(filename
, "r");
652 fp
= fopen("/etc/jackdrc", "r");
654 /* if still not found, check old config name for backwards compatability */
656 fp
= fopen("/etc/jackd.conf", "r");
661 ret
= fscanf(fp
, "%s", buffer
);
662 while(ret
!= 0 && ret
!= EOF
) {
663 strcat(arguments
, buffer
);
664 strcat(arguments
, " ");
665 ret
= fscanf(fp
, "%s", buffer
);
667 if (strlen(arguments
) > 0) {
673 #if defined(USE_CAPABILITIES)
674 command
= JACK_LOCATION
"/jackstart";
675 strncpy(arguments
, JACK_LOCATION
"/jackstart -T -R -d "
676 JACK_DEFAULT_DRIVER
" -p 512", 255);
677 #else /* !USE_CAPABILITIES */
678 command
= JACK_LOCATION
"/jackd";
679 strncpy(arguments
, JACK_LOCATION
"/jackd -T -d "
680 JACK_DEFAULT_DRIVER
, 255);
681 #endif /* USE_CAPABILITIES */
683 result
= strcspn(arguments
, " ");
684 command
= (char *) malloc(result
+1);
685 strncpy(command
, arguments
, result
);
686 command
[result
] = '\0';
689 argv
= (char **) malloc (255);
692 /* insert -T and -nserver_name in front of arguments */
694 argv
[i
] = (char *) malloc(strlen ("-T") + 1);
695 strcpy (argv
[i
++], "-T");
697 size_t optlen
= strlen ("-n");
700 + strlen (server_name
) + 1);
702 strcpy (buf
+optlen
, server_name
);
707 result
= strcspn(arguments
+pos
, " ");
711 argv
[i
] = (char*)malloc(result
+1);
713 strncpy(argv
[i
], arguments
+pos
, result
);
714 argv
[i
][result
] = '\0';
722 fprintf (stderr
, "execing JACK using %s\n", command
);
723 for (_xx
= 0; argv
[_xx
]; ++_xx
) {
724 fprintf (stderr
, "\targv[%d] = %s\n", _xx
, argv
[_xx
]);
728 execv (command
, argv
);
730 /* If execv() succeeds, it does not return. There's no point
731 * in calling jack_error() here in the child process. */
732 fprintf (stderr
, "exec of JACK server (command = \"%s\") failed: %s\n", command
, strerror (errno
));
736 start_server (const char *server_name
, jack_options_t options
)
738 if ((options
& JackNoStartServer
)
739 || getenv("JACK_NO_START_SERVER")) {
743 /* The double fork() forces the server to become a child of
744 * init, which will always clean up zombie process state on
745 * termination. This even works in cases where the server
746 * terminates but this client does not.
748 * Since fork() is usually implemented using copy-on-write
749 * virtual memory tricks, the overhead of the second fork() is
750 * probably relatively small.
753 case 0: /* child process */
755 case 0: /* grandchild process */
756 _start_server(server_name
);
757 _exit (99); /* exec failed */
763 case -1: /* fork() error */
764 return 1; /* failed to start server */
767 /* only the original parent process goes here */
768 return 0; /* (probably) successful */
772 jack_request_client (ClientType type
,
773 const char* client_name
, jack_options_t options
,
774 jack_status_t
*status
, jack_varargs_t
*va
,
775 jack_client_connect_result_t
*res
, int *req_fd
)
777 jack_client_connect_request_t req
;
780 memset (&req
, 0, sizeof (req
));
781 req
.options
= options
;
783 if (strlen (client_name
) >= sizeof (req
.name
)) {
784 jack_error ("\"%s\" is too long to be used as a JACK client"
786 "Please use %lu characters or less.",
787 client_name
, sizeof (req
.name
));
792 && (strlen (va
->load_name
) > sizeof (req
.object_path
) - 1)) {
793 jack_error ("\"%s\" is too long to be used as a JACK shared"
795 "Please use %lu characters or less.",
796 va
->load_name
, sizeof (req
.object_path
) - 1);
801 && (strlen (va
->load_init
) > sizeof (req
.object_data
) - 1)) {
802 jack_error ("\"%s\" is too long to be used as a JACK shared"
803 " object data string.\n"
804 "Please use %lu characters or less.",
805 va
->load_init
, sizeof (req
.object_data
) - 1);
809 if ((*req_fd
= server_connect (va
->server_name
)) < 0) {
811 if (start_server(va
->server_name
, options
)) {
812 *status
|= (JackFailure
|JackServerFailed
);
819 *status
|= (JackFailure
|JackServerFailed
);
822 } while ((*req_fd
= server_connect (va
->server_name
)) < 0);
823 *status
|= JackServerStarted
;
826 /* format connection request */
828 req
.protocol_v
= jack_protocol_version
;
831 snprintf (req
.name
, sizeof (req
.name
),
833 snprintf (req
.object_path
, sizeof (req
.object_path
),
834 "%s", va
->load_name
);
835 snprintf (req
.object_data
, sizeof (req
.object_data
),
836 "%s", va
->load_init
);
838 if (write (*req_fd
, &req
, sizeof (req
)) != sizeof (req
)) {
839 jack_error ("cannot send request to jack server (%s)",
841 *status
|= (JackFailure
|JackServerError
);
845 if (read (*req_fd
, res
, sizeof (*res
)) != sizeof (*res
)) {
848 /* server shut the socket */
849 jack_error ("could not attach as client");
850 *status
|= (JackFailure
|JackServerError
);
854 if (errno
== ECONNRESET
) {
855 jack_error ("could not attach as JACK client "
856 "(server has exited)");
857 *status
|= (JackFailure
|JackServerError
);
861 jack_error ("cannot read response from jack server (%s)",
863 *status
|= (JackFailure
|JackServerError
);
867 *status
|= res
->status
; /* return server status bits */
869 if (*status
& JackFailure
) {
870 if (*status
& JackVersionError
) {
871 jack_error ("client linked with incompatible libjack"
874 jack_error ("could not attach to JACK server");
875 *status
|= JackServerError
;
901 jack_attach_port_segment (jack_client_t
*client
, jack_port_type_id_t ptid
)
903 /* Lookup, attach and register the port/buffer segments in use
907 if (client
->control
->type
!= ClientExternal
) {
908 jack_error("Only external clients need attach port segments");
912 /* make sure we have space to store the port
916 if (ptid
>= client
->n_port_types
) {
918 client
->port_segment
= (jack_shm_info_t
*)
919 realloc (client
->port_segment
,
920 sizeof (jack_shm_info_t
) * (ptid
+1));
922 memset (&client
->port_segment
[client
->n_port_types
],
924 sizeof (jack_shm_info_t
) *
925 (ptid
- client
->n_port_types
));
927 client
->n_port_types
= ptid
+ 1;
931 /* release any previous segment */
932 jack_release_shm (&client
->port_segment
[ptid
]);
935 /* get the index into the shm registry */
937 client
->port_segment
[ptid
].index
=
938 client
->engine
->port_types
[ptid
].shm_registry_index
;
940 /* attach the relevant segment */
942 if (jack_attach_shm (&client
->port_segment
[ptid
])) {
943 jack_error ("cannot attach port segment shared memory"
944 " (%s)", strerror (errno
));
952 jack_client_open_aux (const char *client_name
,
953 jack_options_t options
,
954 jack_status_t
*status
, va_list ap
)
956 /* optional arguments: */
957 jack_varargs_t va
; /* variable arguments */
961 jack_client_connect_result_t res
;
962 jack_client_t
*client
;
963 jack_port_type_id_t ptid
;
964 jack_status_t my_status
;
966 jack_messagebuffer_init ();
968 if (status
== NULL
) /* no status from caller? */
969 status
= &my_status
; /* use local status word */
972 /* validate parameters */
973 if ((options
& ~JackOpenOptions
)) {
974 *status
|= (JackFailure
|JackInvalidOption
);
975 jack_messagebuffer_exit ();
979 /* parse variable arguments */
980 jack_varargs_parse(options
, ap
, &va
);
982 /* External clients need to know where the tmpdir used for
983 communication with the server lives
985 if (jack_get_tmpdir ()) {
986 *status
|= JackFailure
;
987 jack_messagebuffer_exit ();
991 /* External clients need this initialized. It is already set
992 * up in the server's address space for internal clients.
996 if (jack_request_client (ClientExternal
, client_name
, options
, status
,
997 &va
, &res
, &req_fd
)) {
998 jack_messagebuffer_exit ();
1002 /* Allocate the jack_client_t structure in local memory.
1003 * Shared memory is not accessible yet. */
1004 client
= jack_client_alloc ();
1005 strcpy (client
->name
, res
.name
);
1006 strcpy (client
->fifo_prefix
, res
.fifo_prefix
);
1007 client
->request_fd
= req_fd
;
1008 client
->pollfd
[EVENT_POLL_INDEX
].events
=
1009 POLLIN
|POLLERR
|POLLHUP
|POLLNVAL
;
1010 #ifndef JACK_USE_MACH_THREADS
1011 client
->pollfd
[WAIT_POLL_INDEX
].events
=
1012 POLLIN
|POLLERR
|POLLHUP
|POLLNVAL
;
1015 /* Don't access shared memory until server connected. */
1016 if (jack_initialize_shm (va
.server_name
)) {
1017 jack_error ("Unable to initialize shared memory.");
1018 *status
|= (JackFailure
|JackShmFailure
);
1022 /* attach the engine control/info block */
1023 client
->engine_shm
.index
= res
.engine_shm_index
;
1024 if (jack_attach_shm (&client
->engine_shm
)) {
1025 jack_error ("cannot attached engine control shared memory"
1030 client
->engine
= (jack_control_t
*) jack_shm_addr (&client
->engine_shm
);
1032 /* initialize clock source as early as possible */
1033 jack_set_clock_source (client
->engine
->clock_source
);
1035 /* now attach the client control block */
1036 client
->control_shm
.index
= res
.client_shm_index
;
1037 if (jack_attach_shm (&client
->control_shm
)) {
1038 jack_error ("cannot attached client control shared memory"
1043 client
->control
= (jack_client_control_t
*)
1044 jack_shm_addr (&client
->control_shm
);
1046 /* Nobody else needs to access this shared memory any more, so
1047 * destroy it. Because we have it attached, it won't vanish
1048 * till we exit (and release it).
1050 jack_destroy_shm (&client
->control_shm
);
1052 client
->n_port_types
= client
->engine
->n_port_types
;
1053 client
->port_segment
= (jack_shm_info_t
*)
1054 malloc (sizeof (jack_shm_info_t
) * client
->n_port_types
);
1056 for (ptid
= 0; ptid
< client
->n_port_types
; ++ptid
) {
1057 client
->port_segment
[ptid
].index
=
1058 client
->engine
->port_types
[ptid
].shm_registry_index
;
1059 client
->port_segment
[ptid
].attached_at
= MAP_FAILED
;
1060 jack_attach_port_segment (client
, ptid
);
1063 /* set up the client so that it does the right thing for an
1066 client
->deliver_request
= oop_client_deliver_request
;
1067 client
->deliver_arg
= client
;
1069 if ((ev_fd
= server_event_connect (client
, va
.server_name
)) < 0) {
1073 client
->event_fd
= ev_fd
;
1075 #ifdef JACK_USE_MACH_THREADS
1076 /* specific resources for server/client real-time thread
1078 client
->clienttask
= mach_task_self();
1080 if (task_get_bootstrap_port(client
->clienttask
, &client
->bp
)){
1081 jack_error ("Can't find bootstrap port");
1085 if (allocate_mach_clientport(client
, res
.portnum
) < 0) {
1086 jack_error("Can't allocate mach port");
1089 #endif /* JACK_USE_MACH_THREADS */
1093 jack_messagebuffer_exit ();
1095 if (client
->engine
) {
1096 jack_release_shm (&client
->engine_shm
);
1099 if (client
->control
) {
1100 jack_release_shm (&client
->control_shm
);
1101 client
->control
= 0;
1114 jack_client_t
* jack_client_open(const char* ext_client_name
, jack_options_t options
, jack_status_t
* status
, ...)
1117 va_start(ap
, status
);
1118 jack_client_t
* res
= jack_client_open_aux(ext_client_name
, options
, status
, ap
);
1124 jack_client_new (const char *client_name
)
1126 jack_options_t options
= JackUseExactName
;
1127 if (getenv("JACK_START_SERVER") == NULL
)
1128 options
|= JackNoStartServer
;
1129 return jack_client_open (client_name
, options
, NULL
);
1133 jack_get_client_name (jack_client_t
*client
)
1135 return client
->name
;
1139 jack_internal_client_new (const char *client_name
,
1140 const char *so_name
, const char *so_data
)
1142 jack_client_connect_result_t res
;
1145 jack_status_t status
;
1146 jack_options_t options
= JackUseExactName
;
1148 if (getenv("JACK_START_SERVER") == NULL
)
1149 options
|= JackNoStartServer
;
1151 jack_varargs_init (&va
);
1152 va
.load_name
= (char *) so_name
;
1153 va
.load_init
= (char *) so_data
;
1155 return jack_request_client (ClientInternal
, client_name
,
1156 options
, &status
, &va
, &res
, &req_fd
);
1160 jack_default_server_name (void)
1163 if ((server_name
= getenv("JACK_DEFAULT_SERVER")) == NULL
)
1164 server_name
= "default";
1168 /* returns the name of the per-user subdirectory of jack_tmpdir */
1170 jack_user_dir (void)
1172 static char user_dir
[PATH_MAX
+1] = "";
1174 /* format the path name on the first call */
1175 if (user_dir
[0] == '\0') {
1176 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
1177 snprintf (user_dir
, sizeof (user_dir
), "%s/jack",
1180 snprintf (user_dir
, sizeof (user_dir
), "%s/jack-%d",
1181 jack_tmpdir
, getuid ());
1188 /* returns the name of the per-server subdirectory of jack_user_dir() */
1190 jack_server_dir (const char *server_name
, char *server_dir
)
1192 /* format the path name into the suppled server_dir char array,
1193 * assuming that server_dir is at least as large as PATH_MAX+1 */
1195 snprintf (server_dir
, PATH_MAX
+1, "%s/%s",
1196 jack_user_dir (), server_name
);
1202 jack_internal_client_close (const char *client_name
)
1204 jack_client_connect_request_t req
;
1206 char *server_name
= jack_default_server_name ();
1209 snprintf (req
.name
, sizeof (req
.name
), "%s", client_name
);
1211 if ((fd
= server_connect (server_name
)) < 0) {
1215 if (write (fd
, &req
, sizeof (req
)) != sizeof(req
)) {
1216 jack_error ("cannot deliver ClientUnload request to JACK "
1220 /* no response to this request */
1227 jack_recompute_total_latencies (jack_client_t
* client
)
1229 jack_request_t request
;
1231 request
.type
= RecomputeTotalLatencies
;
1232 return jack_client_deliver_request (client
, &request
);
1236 jack_recompute_total_latency (jack_client_t
* client
, jack_port_t
* port
)
1238 jack_request_t request
;
1240 request
.type
= RecomputeTotalLatency
;
1241 request
.x
.port_info
.port_id
= port
->shared
->id
;
1242 return jack_client_deliver_request (client
, &request
);
1246 jack_set_freewheel (jack_client_t
* client
, int onoff
)
1248 jack_request_t request
;
1250 request
.type
= onoff
? FreeWheel
: StopFreeWheel
;
1251 return jack_client_deliver_request (client
, &request
);
1255 jack_start_freewheel (jack_client_t
* client
)
1257 jack_client_control_t
*control
= client
->control
;
1259 if (client
->engine
->real_time
) {
1260 #if JACK_USE_MACH_THREADS
1261 jack_drop_real_time_scheduling (client
->process_thread
);
1263 jack_drop_real_time_scheduling (client
->thread
);
1267 if (control
->freewheel_cb_cbset
) {
1268 client
->freewheel_cb (1, client
->freewheel_arg
);
1273 jack_stop_freewheel (jack_client_t
* client
)
1275 jack_client_control_t
*control
= client
->control
;
1277 if (client
->engine
->real_time
) {
1278 #if JACK_USE_MACH_THREADS
1279 jack_acquire_real_time_scheduling (client
->process_thread
,
1280 client
->engine
->client_priority
);
1282 jack_acquire_real_time_scheduling (client
->thread
,
1283 client
->engine
->client_priority
);
1287 if (control
->freewheel_cb_cbset
) {
1288 client
->freewheel_cb (0, client
->freewheel_arg
);
1293 jack_client_thread_suicide (jack_client_t
* client
)
1295 if (client
->on_info_shutdown
) {
1296 jack_error ("zombified - calling shutdown handler");
1297 client
->on_info_shutdown (JackClientZombie
, "Zombified", client
->on_info_shutdown_arg
);
1298 } else if (client
->on_shutdown
) {
1299 jack_error ("zombified - calling shutdown handler");
1300 client
->on_shutdown (client
->on_shutdown_arg
);
1302 jack_error ("jack_client_thread zombified - exiting from JACK");
1303 jack_client_close_aux (client
);
1304 /* Need a fix : possibly make client crash if
1305 * zombified without shutdown handler
1314 jack_client_process_events (jack_client_t
* client
)
1318 jack_client_control_t
*control
= client
->control
;
1322 DEBUG ("process events");
1324 if (client
->pollfd
[EVENT_POLL_INDEX
].revents
& POLLIN
) {
1326 DEBUG ("client receives an event, "
1327 "now reading on event fd");
1329 /* server has sent us an event. process the
1330 * event and reply */
1332 if (read (client
->event_fd
, &event
, sizeof (event
))
1333 != sizeof (event
)) {
1334 jack_error ("cannot read server event (%s)",
1341 switch (event
.type
) {
1342 case PortRegistered
:
1343 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
1345 if (port
->shared
->id
== event
.x
.port_id
) { // Found port, update port type
1346 port
->type_info
= &client
->engine
->port_types
[port
->shared
->ptype_id
];
1349 if (control
->port_register_cbset
) {
1350 client
->port_register
1351 (event
.x
.port_id
, TRUE
,
1352 client
->port_register_arg
);
1356 case PortUnregistered
:
1357 if (control
->port_register_cbset
) {
1358 client
->port_register
1359 (event
.x
.port_id
, FALSE
,
1360 client
->port_register_arg
);
1364 case ClientRegistered
:
1365 if (control
->client_register_cbset
) {
1366 client
->client_register
1367 (event
.x
.name
, TRUE
,
1368 client
->client_register_arg
);
1372 case ClientUnregistered
:
1373 if (control
->client_register_cbset
) {
1374 client
->client_register
1375 (event
.x
.name
, FALSE
,
1376 client
->client_register_arg
);
1380 case GraphReordered
:
1381 status
= jack_handle_reorder (client
, &event
);
1385 case PortDisconnected
:
1386 status
= jack_client_handle_port_connection
1390 case BufferSizeChange
:
1391 jack_client_invalidate_port_buffers (client
);
1392 if (control
->bufsize_cbset
) {
1393 status
= client
->bufsize
1395 client
->bufsize_arg
);
1399 case SampleRateChange
:
1400 if (control
->srate_cbset
) {
1401 status
= client
->srate
1408 if (control
->xrun_cbset
) {
1409 status
= client
->xrun
1414 case AttachPortSegment
:
1415 jack_attach_port_segment (client
, event
.y
.ptid
);
1418 case StartFreewheel
:
1419 jack_start_freewheel (client
);
1423 jack_stop_freewheel (client
);
1427 DEBUG ("client has dealt with the event, writing "
1428 "response on event fd");
1430 if (write (client
->event_fd
, &status
, sizeof (status
))
1431 != sizeof (status
)) {
1432 jack_error ("cannot send event response to "
1433 "engine (%s)", strerror (errno
));
1442 jack_client_core_wait (jack_client_t
* client
)
1444 jack_client_control_t
*control
= client
->control
;
1446 DEBUG ("client polling on %s", client
->pollmax
== 2 ? x
1447 "event_fd and graph_wait_fd..." :
1451 if (poll (client
->pollfd
, client
->pollmax
, 1000) < 0) {
1452 if (errno
== EINTR
) {
1455 jack_error ("poll failed in client (%s)",
1460 pthread_testcancel();
1462 #ifndef JACK_USE_MACH_THREADS
1464 /* get an accurate timestamp on waking from poll for a
1468 if (client
->graph_wait_fd
>= 0
1469 && client
->pollfd
[WAIT_POLL_INDEX
].revents
& POLLIN
) {
1470 control
->awake_at
= jack_get_microseconds();
1473 DEBUG ("pfd[EVENT].revents = 0x%x pfd[WAIT].revents = 0x%x",
1474 client
->pollfd
[EVENT_POLL_INDEX
].revents
,
1475 client
->pollfd
[WAIT_POLL_INDEX
].revents
);
1477 if (client
->graph_wait_fd
>= 0 &&
1478 (client
->pollfd
[WAIT_POLL_INDEX
].revents
& ~POLLIN
)) {
1480 /* our upstream "wait" connection
1481 closed, which either means that
1482 an intermediate client exited, or
1483 jackd exited, or jackd zombified
1486 we can discover the zombification
1487 via client->control->dead, but
1488 the other two possibilities are
1489 impossible to identify just from
1490 this situation. so we have to
1491 check what we are connected to,
1492 and act accordingly.
1495 if (client
->upstream_is_jackd
) {
1499 DEBUG ("WE PUNT\n");
1500 /* don't poll on the wait fd
1501 * again until we get a
1502 * GraphReordered event.
1505 client
->graph_wait_fd
= -1;
1506 client
->pollmax
= 1;
1511 if (jack_client_process_events (client
)) {
1512 DEBUG ("event processing failed\n");
1516 if (client
->graph_wait_fd
>= 0 &&
1517 (client
->pollfd
[WAIT_POLL_INDEX
].revents
& POLLIN
)) {
1518 DEBUG ("time to run process()\n");
1523 if (control
->dead
|| client
->pollfd
[EVENT_POLL_INDEX
].revents
& ~POLLIN
) {
1524 DEBUG ("client appears dead or event pollfd has error status\n");
1532 jack_wake_next_client (jack_client_t
* client
)
1534 struct pollfd pfds
[1];
1538 if (write (client
->graph_next_fd
, &c
, sizeof (c
))
1540 DEBUG("cannot write byte to fd %d", client
->graph_next_fd
);
1541 jack_error ("cannot continue execution of the "
1542 "processing graph (%s)",
1547 DEBUG ("client sent message to next stage by %" PRIu64
"",
1548 jack_get_microseconds());
1550 DEBUG("reading cleanup byte from pipe %d\n", client
->graph_wait_fd
);
1552 /* "upstream client went away? readability is checked in
1553 * jack_client_core_wait(), but that's almost a whole cycle
1554 * before we get here.
1557 if (client
->graph_wait_fd
>= 0) {
1558 pfds
[0].fd
= client
->graph_wait_fd
;
1559 pfds
[0].events
= POLLIN
;
1561 /* 0 timeout, don't actually wait */
1562 pret
= poll(pfds
, 1, 0);
1565 if (pret
> 0 && (pfds
[0].revents
& POLLIN
)) {
1566 if (read (client
->graph_wait_fd
, &c
, sizeof (c
))
1568 jack_error ("cannot complete execution of the "
1569 "processing graph (%s)", strerror(errno
));
1573 DEBUG("cleanup byte from pipe %d not available?\n",
1574 client
->graph_wait_fd
);
1580 static jack_nframes_t
1581 jack_thread_first_wait (jack_client_t
* client
)
1583 if (jack_client_core_wait (client
)) {
1586 return client
->control
->nframes
;
1590 jack_thread_wait (jack_client_t
* client
, int status
)
1592 client
->control
->last_status
= status
;
1594 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1596 /* housekeeping/cleanup after data processing */
1598 if (status
== 0 && client
->control
->timebase_cb_cbset
) {
1599 jack_call_timebase_master (client
);
1602 /* end preemption checking */
1603 CHECK_PREEMPTION (client
->engine
, FALSE
);
1605 client
->control
->finished_at
= jack_get_microseconds();
1607 /* wake the next client in the chain (could be the server),
1608 and check if we were killed during the process
1612 if (jack_wake_next_client (client
)) {
1613 DEBUG("client cannot wake next, or is dead\n");
1617 if (status
|| client
->control
->dead
|| !client
->engine
->engine_ok
) {
1621 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1623 if (jack_client_core_wait (client
)) {
1627 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1629 /* Time to do data processing */
1631 client
->control
->state
= Running
;
1633 /* begin preemption checking */
1634 CHECK_PREEMPTION (client
->engine
, TRUE
);
1636 if (client
->control
->sync_cb_cbset
)
1637 jack_call_sync_client (client
);
1639 return client
->control
->nframes
;
1642 jack_nframes_t
jack_cycle_wait (jack_client_t
* client
)
1644 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1646 if (jack_client_core_wait (client
)) {
1650 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1652 /* Time to do data processing */
1654 client
->control
->state
= Running
;
1656 /* begin preemption checking */
1657 CHECK_PREEMPTION (client
->engine
, TRUE
);
1659 if (client
->control
->sync_cb_cbset
)
1660 jack_call_sync_client (client
);
1662 return client
->control
->nframes
;
1665 void jack_cycle_signal(jack_client_t
* client
, int status
)
1667 client
->control
->last_status
= status
;
1669 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1671 /* housekeeping/cleanup after data processing */
1673 if (status
== 0 && client
->control
->timebase_cb_cbset
) {
1674 jack_call_timebase_master (client
);
1677 /* end preemption checking */
1678 CHECK_PREEMPTION (client
->engine
, FALSE
);
1680 client
->control
->finished_at
= jack_get_microseconds();
1682 /* wake the next client in the chain (could be the server),
1683 and check if we were killed during the process
1687 if (jack_wake_next_client (client
)) {
1688 DEBUG("client cannot wake next, or is dead\n");
1689 jack_client_thread_suicide (client
);
1693 if (status
|| client
->control
->dead
|| !client
->engine
->engine_ok
) {
1694 jack_client_thread_suicide (client
);
1700 jack_client_thread_aux (void *arg
)
1702 jack_client_t
*client
= (jack_client_t
*) arg
;
1703 jack_client_control_t
*control
= client
->control
;
1705 pthread_mutex_lock (&client_lock
);
1706 client
->thread_ok
= TRUE
;
1707 client
->thread_id
= pthread_self();
1708 pthread_cond_signal (&client_ready
);
1709 pthread_mutex_unlock (&client_lock
);
1711 control
->pid
= getpid();
1712 control
->pgrp
= getpgrp();
1714 DEBUG ("client thread is now running");
1716 if (control
->thread_init_cbset
) {
1717 DEBUG ("calling client thread init callback");
1718 client
->thread_init (client
->thread_init_arg
);
1721 /* wait for first wakeup from server */
1723 if (jack_thread_first_wait (client
) == control
->nframes
) {
1725 /* now run till we're done */
1727 if (control
->process_cbset
) {
1729 /* run process callback, then wait... ad-infinitum */
1732 DEBUG("client calls process()");
1733 int status
= (client
->process (control
->nframes
,
1734 client
->process_arg
) ==
1736 control
->state
= Finished
;
1737 DEBUG("client leaves process(), re-enters wait");
1738 if (!jack_thread_wait (client
, status
)) {
1741 DEBUG("client done with wait");
1745 /* no process handling but still need to process events */
1746 while (jack_thread_wait (client
, 0) == control
->nframes
)
1751 jack_client_thread_suicide (client
);
1755 jack_client_thread (void *arg
)
1757 jack_client_t
*client
= (jack_client_t
*) arg
;
1758 jack_client_control_t
*control
= client
->control
;
1760 if (client
->control
->thread_cb_cbset
) {
1762 pthread_mutex_lock (&client_lock
);
1763 client
->thread_ok
= TRUE
;
1764 client
->thread_id
= pthread_self();
1765 pthread_cond_signal (&client_ready
);
1766 pthread_mutex_unlock (&client_lock
);
1768 control
->pid
= getpid();
1769 control
->pgrp
= getpgrp();
1771 client
->thread_cb(client
->thread_cb_arg
);
1772 jack_client_thread_suicide(client
);
1774 jack_client_thread_aux(arg
);
1781 #ifdef JACK_USE_MACH_THREADS
1782 /* real-time thread : separated from the normal client thread, it will
1783 * communicate with the server using fast mach RPC mechanism */
1786 jack_client_process_thread (void *arg
)
1788 jack_client_t
*client
= (jack_client_t
*) arg
;
1789 jack_client_control_t
*control
= client
->control
;
1792 if (client
->control
->thread_init_cbset
) {
1793 /* this means that the init callback will be called twice -taybin*/
1794 DEBUG ("calling client thread init callback");
1795 client
->thread_init (client
->thread_init_arg
);
1798 client
->control
->pid
= getpid();
1799 DEBUG ("client process thread is now running");
1801 client
->rt_thread_ok
= TRUE
;
1805 if (jack_client_suspend(client
) < 0) {
1806 jack_error ("jack_client_process_thread :resume error");
1810 control
->awake_at
= jack_get_microseconds();
1812 DEBUG ("client resumed");
1814 control
->state
= Running
;
1816 if (control
->sync_cb_cbset
)
1817 jack_call_sync_client (client
);
1819 if (control
->process_cbset
) {
1820 if (client
->process (control
->nframes
,
1821 client
->process_arg
) == 0) {
1822 control
->state
= Finished
;
1825 control
->state
= Finished
;
1828 if (control
->timebase_cb_cbset
)
1829 jack_call_timebase_master (client
);
1831 control
->finished_at
= jack_get_microseconds();
1833 DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
1834 control
->finished_at
,
1835 ((float)(control
->finished_at
- control
->awake_at
)));
1837 /* check if we were killed during the process cycle
1840 if (client
->control
->dead
) {
1841 jack_error ("jack_client_process_thread: "
1842 "client->control->dead");
1846 DEBUG("process cycle fully complete\n");
1850 return (void *) ((intptr_t)err
);
1854 jack_error ("jack_client_process_thread : zombified");
1856 client
->rt_thread_ok
= FALSE
;
1858 if (client
->on_info_shutdown
) {
1859 jack_error ("zombified - calling shutdown handler");
1860 client
->on_info_shutdown (JackClientZombie
, "Zombified", client
->on_info_shutdown_arg
);
1861 } else if (client
->on_shutdown
) {
1862 jack_error ("zombified - calling shutdown handler");
1863 client
->on_shutdown (client
->on_shutdown_arg
);
1865 jack_error ("jack_client_process_thread zombified - exiting from JACK");
1866 /* Need a fix : possibly make client crash if
1867 * zombified without shutdown handler */
1868 jack_client_close_aux (client
);
1875 #endif /* JACK_USE_MACH_THREADS */
1878 jack_start_thread (jack_client_t
*client
)
1880 if (client
->engine
->real_time
) {
1883 if (client
->engine
->do_mlock
1884 && (mlockall (MCL_CURRENT
| MCL_FUTURE
) != 0)) {
1885 jack_error ("cannot lock down memory for RT thread "
1886 "(%s)", strerror (errno
));
1890 #endif /* ENSURE_MLOCK */
1893 if (client
->engine
->do_munlock
) {
1896 #endif /* USE_MLOCK */
1899 #ifdef JACK_USE_MACH_THREADS
1900 /* Stephane Letz : letz@grame.fr
1901 On MacOSX, the normal thread does not need to be real-time.
1903 if (jack_client_create_thread (client
,
1905 client
->engine
->client_priority
,
1907 jack_client_thread
, client
)) {
1911 if (jack_client_create_thread (client
,
1913 client
->engine
->client_priority
,
1914 client
->engine
->real_time
,
1915 jack_client_thread
, client
)) {
1921 #ifdef JACK_USE_MACH_THREADS
1923 /* a secondary thread that runs the process callback and uses
1924 ultra-fast Mach primitives for inter-thread signalling.
1926 XXX in a properly structured JACK, there would be no
1927 need for this, because we would have client wake up
1928 methods that encapsulated the underlying mechanism
1933 if (jack_client_create_thread(client
,
1934 &client
->process_thread
,
1935 client
->engine
->client_priority
,
1936 client
->engine
->real_time
,
1937 jack_client_process_thread
, client
)) {
1940 #endif /* JACK_USE_MACH_THREADS */
1946 jack_activate (jack_client_t
*client
)
1950 /* we need to scribble on our stack to ensure that its memory
1951 * pages are actually mapped (more important for mlockall(2)
1952 * usage in jack_start_thread())
1955 char buf
[JACK_THREAD_STACK_TOUCH
];
1958 for (i
= 0; i
< JACK_THREAD_STACK_TOUCH
; i
++) {
1959 buf
[i
] = (char) (i
& 0xff);
1962 if (client
->control
->type
== ClientInternal
||
1963 client
->control
->type
== ClientDriver
) {
1967 /* get the pid of the client process to pass it to engine */
1969 client
->control
->pid
= getpid ();
1971 #ifdef USE_CAPABILITIES
1973 if (client
->engine
->has_capabilities
!= 0 &&
1974 client
->control
->pid
!= 0 && client
->engine
->real_time
!= 0) {
1976 /* we need to ask the engine for realtime capabilities
1977 before trying to start the realtime thread
1980 req
.type
= SetClientCapabilities
;
1981 req
.x
.client_id
= client
->control
->id
;
1982 req
.x
.cap_pid
= client
->control
->pid
;
1984 jack_client_deliver_request (client
, &req
);
1988 /* what to do? engine is running realtime, it
1989 is using capabilities and has them
1990 (otherwise we would not get an error
1991 return) but for some reason it could not
1992 give the client the required capabilities.
1993 For now, leave the client so that it
1994 still runs, albeit non-realtime.
1997 jack_error ("could not receive realtime capabilities, "
1998 "client will run non-realtime");
2001 #endif /* USE_CAPABILITIES */
2003 if (client
->first_active
) {
2005 pthread_mutex_init (&client_lock
, NULL
);
2006 pthread_cond_init (&client_ready
, NULL
);
2008 pthread_mutex_lock (&client_lock
);
2010 if (jack_start_thread (client
)) {
2011 pthread_mutex_unlock (&client_lock
);
2015 pthread_cond_wait (&client_ready
, &client_lock
);
2016 pthread_mutex_unlock (&client_lock
);
2018 if (!client
->thread_ok
) {
2019 jack_error ("could not start client thread");
2023 client
->first_active
= FALSE
;
2028 req
.type
= ActivateClient
;
2029 req
.x
.client_id
= client
->control
->id
;
2031 return jack_client_deliver_request (client
, &req
);
2035 jack_deactivate_aux (jack_client_t
*client
)
2038 int rc
= ESRCH
; /* already shut down */
2040 if (client
&& client
->control
) { /* not shut down? */
2042 if (client
->control
->active
) { /* still active? */
2043 req
.type
= DeactivateClient
;
2044 req
.x
.client_id
= client
->control
->id
;
2045 rc
= jack_client_deliver_request (client
, &req
);
2052 jack_deactivate (jack_client_t
*client
)
2054 return jack_deactivate_aux(client
);
2058 jack_client_close_aux (jack_client_t
*client
)
2064 rc
= jack_deactivate_aux (client
);
2065 if (rc
== ESRCH
) { /* already shut down? */
2069 if (client
->control
->type
== ClientExternal
) {
2071 #if JACK_USE_MACH_THREADS
2072 if (client
->rt_thread_ok
) {
2073 // MacOSX pthread_cancel not implemented in
2075 mach_port_t machThread
=
2076 pthread_mach_thread_np (client
->process_thread
);
2077 thread_terminate (machThread
);
2081 /* stop the thread that communicates with the jack
2082 * server, only if it was actually running
2085 if (client
->thread_ok
){
2086 pthread_cancel (client
->thread
);
2087 pthread_join (client
->thread
, &status
);
2090 if (client
->control
) {
2091 jack_release_shm (&client
->control_shm
);
2092 client
->control
= NULL
;
2094 if (client
->engine
) {
2095 jack_release_shm (&client
->engine_shm
);
2096 client
->engine
= NULL
;
2099 if (client
->port_segment
) {
2100 jack_port_type_id_t ptid
;
2101 for (ptid
= 0; ptid
< client
->n_port_types
; ++ptid
) {
2102 jack_release_shm (&client
->port_segment
[ptid
]);
2104 free (client
->port_segment
);
2105 client
->port_segment
= NULL
;
2108 #ifndef JACK_USE_MACH_THREADS
2109 if (client
->graph_wait_fd
>= 0) {
2110 close (client
->graph_wait_fd
);
2113 if (client
->graph_next_fd
>= 0) {
2114 close (client
->graph_next_fd
);
2118 close (client
->event_fd
);
2120 if (shutdown (client
->request_fd
, SHUT_RDWR
)) {
2121 jack_error ("could not shutdown client request socket");
2124 close (client
->request_fd
);
2128 for (node
= client
->ports
; node
; node
= jack_slist_next (node
)) {
2131 jack_slist_free (client
->ports
);
2132 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
2135 jack_slist_free (client
->ports_ext
);
2136 jack_client_free (client
);
2137 jack_messagebuffer_exit ();
2143 jack_client_close (jack_client_t
*client
)
2145 return jack_client_close_aux(client
);
2149 jack_is_realtime (jack_client_t
*client
)
2151 return client
->engine
->real_time
;
2155 jack_get_buffer_size (jack_client_t
*client
)
2157 return client
->engine
->buffer_size
;
2161 jack_set_buffer_size (jack_client_t
*client
, jack_nframes_t nframes
)
2163 #ifdef DO_BUFFER_RESIZE
2166 req
.type
= SetBufferSize
;
2167 req
.x
.nframes
= nframes
;
2169 return jack_client_deliver_request (client
, &req
);
2173 #endif /* DO_BUFFER_RESIZE */
2177 jack_connect (jack_client_t
*client
, const char *source_port
,
2178 const char *destination_port
)
2182 req
.type
= ConnectPorts
;
2184 snprintf (req
.x
.connect
.source_port
,
2185 sizeof (req
.x
.connect
.source_port
), "%s", source_port
);
2186 snprintf (req
.x
.connect
.destination_port
,
2187 sizeof (req
.x
.connect
.destination_port
),
2188 "%s", destination_port
);
2190 return jack_client_deliver_request (client
, &req
);
2194 jack_port_disconnect (jack_client_t
*client
, jack_port_t
*port
)
2198 pthread_mutex_lock (&port
->connection_lock
);
2200 if (port
->connections
== NULL
) {
2201 pthread_mutex_unlock (&port
->connection_lock
);
2205 pthread_mutex_unlock (&port
->connection_lock
);
2207 req
.type
= DisconnectPort
;
2208 req
.x
.port_info
.port_id
= port
->shared
->id
;
2210 return jack_client_deliver_request (client
, &req
);
2214 jack_disconnect (jack_client_t
*client
, const char *source_port
,
2215 const char *destination_port
)
2219 req
.type
= DisconnectPorts
;
2221 snprintf (req
.x
.connect
.source_port
,
2222 sizeof (req
.x
.connect
.source_port
), "%s", source_port
);
2223 snprintf (req
.x
.connect
.destination_port
,
2224 sizeof (req
.x
.connect
.destination_port
),
2225 "%s", destination_port
);
2227 return jack_client_deliver_request (client
, &req
);
2231 jack_set_error_function (void (*func
) (const char *))
2233 jack_error_callback
= func
;
2237 jack_set_info_function (void (*func
) (const char *))
2239 jack_info_callback
= func
;
2243 jack_set_graph_order_callback (jack_client_t
*client
,
2244 JackGraphOrderCallback callback
, void *arg
)
2246 if (client
->control
->active
) {
2247 jack_error ("You cannot set callbacks on an active client.");
2250 client
->graph_order
= callback
;
2251 client
->graph_order_arg
= arg
;
2252 client
->control
->graph_order_cbset
= (callback
!= NULL
);
2256 int jack_set_xrun_callback (jack_client_t
*client
,
2257 JackXRunCallback callback
, void *arg
)
2259 if (client
->control
->active
) {
2260 jack_error ("You cannot set callbacks on an active client.");
2264 client
->xrun
= callback
;
2265 client
->xrun_arg
= arg
;
2266 client
->control
->xrun_cbset
= (callback
!= NULL
);
2271 jack_set_process_callback (jack_client_t
*client
,
2272 JackProcessCallback callback
, void *arg
)
2275 if (client
->control
->active
) {
2276 jack_error ("You cannot set callbacks on an active client.");
2280 if (client
->control
->thread_cb_cbset
) {
2281 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
2285 client
->process_arg
= arg
;
2286 client
->process
= callback
;
2287 client
->control
->process_cbset
= (callback
!= NULL
);
2292 jack_set_thread_init_callback (jack_client_t
*client
,
2293 JackThreadInitCallback callback
, void *arg
)
2296 if (client
->control
->active
) {
2297 jack_error ("You cannot set callbacks on an active client.");
2300 client
->thread_init_arg
= arg
;
2301 client
->thread_init
= callback
;
2302 client
->control
->thread_init_cbset
= (callback
!= NULL
);
2307 jack_set_freewheel_callback (jack_client_t
*client
,
2308 JackFreewheelCallback callback
, void *arg
)
2310 if (client
->control
->active
) {
2311 jack_error ("You cannot set callbacks on an active client.");
2314 client
->freewheel_arg
= arg
;
2315 client
->freewheel_cb
= callback
;
2316 client
->control
->freewheel_cb_cbset
= (callback
!= NULL
);
2321 jack_set_buffer_size_callback (jack_client_t
*client
,
2322 JackBufferSizeCallback callback
, void *arg
)
2324 client
->bufsize_arg
= arg
;
2325 client
->bufsize
= callback
;
2326 client
->control
->bufsize_cbset
= (callback
!= NULL
);
2331 jack_set_port_registration_callback(jack_client_t
*client
,
2332 JackPortRegistrationCallback callback
,
2335 if (client
->control
->active
) {
2336 jack_error ("You cannot set callbacks on an active client.");
2339 client
->port_register_arg
= arg
;
2340 client
->port_register
= callback
;
2341 client
->control
->port_register_cbset
= (callback
!= NULL
);
2346 jack_set_port_connect_callback(jack_client_t
*client
,
2347 JackPortConnectCallback callback
,
2350 if (client
->control
->active
) {
2351 jack_error ("You cannot set callbacks on an active client.");
2354 client
->port_connect_arg
= arg
;
2355 client
->port_connect
= callback
;
2356 client
->control
->port_connect_cbset
= (callback
!= NULL
);
2361 jack_set_client_registration_callback(jack_client_t
*client
,
2362 JackClientRegistrationCallback callback
,
2365 if (client
->control
->active
) {
2366 jack_error ("You cannot set callbacks on an active client.");
2369 client
->client_register_arg
= arg
;
2370 client
->client_register
= callback
;
2371 client
->control
->client_register_cbset
= (callback
!= NULL
);
2376 jack_set_process_thread(jack_client_t
* client
, JackThreadCallback callback
, void *arg
)
2378 if (client
->control
->active
) {
2379 jack_error ("You cannot set callbacks on an active client.");
2383 if (client
->control
->process_cbset
) {
2384 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
2388 client
->thread_cb_arg
= arg
;
2389 client
->thread_cb
= callback
;
2390 client
->control
->thread_cb_cbset
= (callback
!= NULL
);
2395 jack_get_process_done_fd (jack_client_t
*client
)
2397 return client
->graph_next_fd
;
2401 jack_on_shutdown (jack_client_t
*client
, void (*function
)(void *arg
), void *arg
)
2403 client
->on_shutdown
= function
;
2404 client
->on_shutdown_arg
= arg
;
2408 jack_on_info_shutdown (jack_client_t
*client
, void (*function
)(jack_status_t
, const char*, void *arg
), void *arg
)
2410 client
->on_info_shutdown
= function
;
2411 client
->on_info_shutdown_arg
= arg
;
2415 jack_get_ports (jack_client_t
*client
,
2416 const char *port_name_pattern
,
2417 const char *type_name_pattern
,
2418 unsigned long flags
)
2420 jack_control_t
*engine
;
2421 const char **matching_ports
;
2422 unsigned long match_cnt
;
2423 jack_port_shared_t
*psp
;
2429 engine
= client
->engine
;
2431 if (port_name_pattern
&& port_name_pattern
[0]) {
2432 regcomp (&port_regex
, port_name_pattern
,
2433 REG_EXTENDED
|REG_NOSUB
);
2435 if (type_name_pattern
&& type_name_pattern
[0]) {
2436 regcomp (&type_regex
, type_name_pattern
,
2437 REG_EXTENDED
|REG_NOSUB
);
2440 psp
= engine
->ports
;
2443 matching_ports
= (const char **)
2444 malloc (sizeof (char *) * engine
->port_max
);
2446 for (i
= 0; i
< engine
->port_max
; i
++) {
2449 if (!psp
[i
].in_use
) {
2454 if ((psp
[i
].flags
& flags
) != flags
) {
2459 if (matching
&& port_name_pattern
&& port_name_pattern
[0]) {
2460 if (regexec (&port_regex
, psp
[i
].name
, 0, NULL
, 0)) {
2465 if (matching
&& type_name_pattern
&& type_name_pattern
[0]) {
2466 jack_port_type_id_t ptid
= psp
[i
].ptype_id
;
2467 if (regexec (&type_regex
,
2468 engine
->port_types
[ptid
].type_name
,
2475 matching_ports
[match_cnt
++] = psp
[i
].name
;
2478 if (port_name_pattern
&& port_name_pattern
[0]) {
2479 regfree (&port_regex
);
2481 if (type_name_pattern
&& type_name_pattern
[0]) {
2482 regfree (&type_regex
);
2485 matching_ports
[match_cnt
] = 0;
2487 if (match_cnt
== 0) {
2488 free (matching_ports
);
2492 return matching_ports
;
2496 jack_cpu_load (jack_client_t
*client
)
2498 return client
->engine
->cpu_load
;
2502 jack_get_xrun_delayed_usecs (jack_client_t
*client
)
2504 return client
->engine
->xrun_delayed_usecs
;
2508 jack_get_max_delayed_usecs (jack_client_t
*client
)
2510 return client
->engine
->max_delayed_usecs
;
2514 jack_reset_max_delayed_usecs (jack_client_t
*client
)
2516 client
->engine
->max_delayed_usecs
= 0.0f
;
2520 jack_client_thread_id (jack_client_t
*client
)
2522 return client
->thread_id
;
2526 jack_client_name_size(void)
2528 return JACK_CLIENT_NAME_SIZE
;
2532 jack_port_name_size(void)
2534 return JACK_PORT_NAME_SIZE
;
2538 jack_port_type_size(void)
2540 return JACK_PORT_TYPE_SIZE
;
2544 jack_free (void* ptr
)