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>
51 #include <jack/messagebuffer.h>
53 #include <sysdeps/time.h>
57 #include <sysdeps/poll.h>
58 #include <sysdeps/ipc.h>
59 #include <sysdeps/cycles.h>
61 #ifdef JACK_USE_MACH_THREADS
62 #include <sysdeps/pThreadUtilities.h>
65 static pthread_mutex_t client_lock
;
66 static pthread_cond_t client_ready
;
69 jack_client_close_aux (jack_client_t
*client
);
71 #define EVENT_POLL_INDEX 0
72 #define WAIT_POLL_INDEX 1
73 #define event_fd pollfd[EVENT_POLL_INDEX].fd
74 #define graph_wait_fd pollfd[WAIT_POLL_INDEX].fd
78 struct _jack_client
*client
;
79 const char *client_name
;
91 cpu_type
= ((have_3dnow() << 8) | have_sse());
92 if (ARCH_X86_HAVE_3DNOW(cpu_type
))
93 jack_info("Enhanced3DNow! detected");
94 if (ARCH_X86_HAVE_SSE2(cpu_type
))
95 jack_info("SSE2 detected");
96 if ((!ARCH_X86_HAVE_3DNOW(cpu_type
)) && (!ARCH_X86_HAVE_SSE2(cpu_type
)))
97 jack_info("No supported SIMD instruction sets detected");
98 jack_port_set_funcs();
106 jack_port_set_funcs();
109 #endif /* ARCH_X86 */
111 #endif /* USE_DYNSIMD */
113 char *jack_tmpdir
= DEFAULT_TMP_DIR
;
120 char buf
[PATH_MAX
+2]; /* allow tmpdir to live anywhere, plus newline, plus null */
125 /* some implementations of popen(3) close a security loophole by
126 resetting PATH for the exec'd command. since we *want* to
127 use the user's PATH setting to locate jackd, we have to
131 if ((pathenv
= getenv ("PATH")) == 0) {
135 /* don't let strtok(3) mess with the real environment variable */
137 if ((pathcopy
= strdup (pathenv
)) == NULL
) {
140 p
= strtok (pathcopy
, ":");
143 char jackd
[PATH_MAX
+1];
144 char command
[PATH_MAX
+4];
146 snprintf (jackd
, sizeof (jackd
), "%s/jackd", p
);
148 if (access (jackd
, X_OK
) == 0) {
150 snprintf (command
, sizeof (command
), "%s -l", jackd
);
152 if ((in
= popen (command
, "r")) != NULL
) {
157 p
= strtok (NULL
, ":");
161 /* no command successfully started */
166 if (fgets (buf
, sizeof (buf
), in
) == NULL
) {
174 if (buf
[len
-1] != '\n') {
175 /* didn't get a whole line */
181 if ((jack_tmpdir
= (char *) malloc (len
)) == NULL
) {
186 memcpy (jack_tmpdir
, buf
, len
-1);
187 jack_tmpdir
[len
-1] = '\0';
196 jack_error (const char *fmt
, ...)
202 vsnprintf (buffer
, sizeof(buffer
), fmt
, ap
);
203 jack_error_callback (buffer
);
208 default_jack_error_callback (const char *desc
)
213 fprintf(stderr
, "%s\n", desc
);
219 default_jack_info_callback (const char *desc
)
221 fprintf(stdout
, "%s\n", desc
);
226 silent_jack_error_callback (const char *desc
)
230 void (*jack_error_callback
)(const char *desc
) = &default_jack_error_callback
;
231 void (*jack_info_callback
)(const char *desc
) = &default_jack_info_callback
;
234 jack_info (const char *fmt
, ...)
240 vsnprintf (buffer
, sizeof(buffer
), fmt
, ap
);
241 jack_info_callback (buffer
);
246 oop_client_deliver_request (void *ptr
, jack_request_t
*req
)
249 jack_client_t
*client
= (jack_client_t
*) ptr
;
251 wok
= (write (client
->request_fd
, req
, sizeof (*req
))
253 rok
= (read (client
->request_fd
, req
, sizeof (*req
))
256 if (wok
&& rok
) { /* everything OK? */
260 req
->status
= -1; /* request failed */
262 /* check for server shutdown */
263 if (client
->engine
->engine_ok
== 0)
266 /* otherwise report errors */
268 jack_error ("cannot send request type %d to server",
271 jack_error ("cannot read result for request type %d from"
272 " server (%s)", req
->type
, strerror (errno
));
277 jack_client_deliver_request (const jack_client_t
*client
, jack_request_t
*req
)
279 /* indirect through the function pointer that was set either
280 * by jack_client_open() or by jack_new_client_request() in
284 return client
->deliver_request (client
->deliver_arg
,
288 #if JACK_USE_MACH_THREADS
293 jack_client_t
*client
;
295 if ((client
= (jack_client_t
*) malloc (sizeof (jack_client_t
))) == NULL
) {
299 if ((client
->pollfd
= (struct pollfd
*) malloc (sizeof (struct pollfd
) * 1)) == NULL
) {
305 client
->request_fd
= -1;
306 client
->event_fd
= -1;
307 client
->upstream_is_jackd
= 0;
308 client
->graph_wait_fd
= -1;
309 client
->graph_next_fd
= -1;
310 client
->ports
= NULL
;
311 client
->ports_ext
= NULL
;
312 client
->engine
= NULL
;
313 client
->control
= NULL
;
314 client
->thread_ok
= FALSE
;
315 client
->rt_thread_ok
= FALSE
;
316 client
->first_active
= TRUE
;
317 client
->on_shutdown
= NULL
;
318 client
->on_info_shutdown
= NULL
;
319 client
->n_port_types
= 0;
320 client
->port_segment
= NULL
;
324 #endif /* USE_DYNSIMD */
334 jack_client_t
*client
;
336 if ((client
= (jack_client_t
*) malloc (sizeof (jack_client_t
))) == NULL
) {
339 if ((client
->pollfd
= (struct pollfd
*) malloc (sizeof (struct pollfd
) * 2)) == NULL
) {
345 client
->request_fd
= -1;
346 client
->event_fd
= -1;
347 client
->upstream_is_jackd
= 0;
348 client
->graph_wait_fd
= -1;
349 client
->graph_next_fd
= -1;
350 client
->ports
= NULL
;
351 client
->ports_ext
= NULL
;
352 client
->engine
= NULL
;
353 client
->control
= NULL
;
354 client
->thread_ok
= FALSE
;
355 client
->first_active
= TRUE
;
356 client
->on_shutdown
= NULL
;
357 client
->on_info_shutdown
= NULL
;
358 client
->n_port_types
= 0;
359 client
->port_segment
= NULL
;
363 #endif /* USE_DYNSIMD */
371 * Build the jack_client_t structure for an internal client.
374 jack_client_alloc_internal (jack_client_control_t
*cc
, jack_engine_t
* engine
)
376 jack_client_t
* client
;
378 client
= jack_client_alloc ();
380 client
->control
= cc
;
381 client
->engine
= engine
->control
;
383 client
->n_port_types
= client
->engine
->n_port_types
;
384 client
->port_segment
= &engine
->port_segment
[0];
390 jack_client_free (jack_client_t
*client
)
392 if (client
->pollfd
) {
393 free (client
->pollfd
);
400 jack_client_invalidate_port_buffers (jack_client_t
*client
)
405 /* This releases all local memory owned by input ports
406 and sets the buffer pointer to NULL. This will cause
407 jack_port_get_buffer() to reallocate space for the
408 buffer on the next call (if there is one).
411 for (node
= client
->ports
; node
; node
= jack_slist_next (node
)) {
412 port
= (jack_port_t
*) node
->data
;
414 if (port
->shared
->flags
& JackPortIsInput
) {
415 if (port
->mix_buffer
) {
416 jack_pool_release (port
->mix_buffer
);
417 port
->mix_buffer
= NULL
;
424 jack_client_handle_port_connection (jack_client_t
*client
, jack_event_t
*event
)
426 jack_port_t
*control_port
;
427 jack_port_t
*other
= 0;
429 int need_free
= FALSE
;
431 if (client
->engine
->ports
[event
->x
.self_id
].client_id
== client
->control
->id
||
432 client
->engine
->ports
[event
->y
.other_id
].client_id
== client
->control
->id
) {
434 /* its one of ours */
436 switch (event
->type
) {
438 other
= jack_port_new (client
, event
->y
.other_id
,
440 /* jack_port_by_id_int() always returns an internal
441 * port that does not need to be deallocated
443 control_port
= jack_port_by_id_int (client
, event
->x
.self_id
,
445 pthread_mutex_lock (&control_port
->connection_lock
);
446 control_port
->connections
=
447 jack_slist_prepend (control_port
->connections
,
449 pthread_mutex_unlock (&control_port
->connection_lock
);
452 case PortDisconnected
:
453 /* jack_port_by_id_int() always returns an internal
454 * port that does not need to be deallocated
456 control_port
= jack_port_by_id_int (client
, event
->x
.self_id
,
458 pthread_mutex_lock (&control_port
->connection_lock
);
460 for (node
= control_port
->connections
; node
;
461 node
= jack_slist_next (node
)) {
463 other
= (jack_port_t
*) node
->data
;
465 if (other
->shared
->id
== event
->y
.other_id
) {
466 control_port
->connections
=
467 jack_slist_remove_link (
468 control_port
->connections
,
470 jack_slist_free_1 (node
);
476 pthread_mutex_unlock (&control_port
->connection_lock
);
485 if (client
->control
->port_connect_cbset
) {
486 client
->port_connect (event
->x
.self_id
, event
->y
.other_id
,
487 (event
->type
== PortConnected
? 1 : 0),
488 client
->port_connect_arg
);
494 #if JACK_USE_MACH_THREADS
497 jack_handle_reorder (jack_client_t
*client
, jack_event_t
*event
)
501 /* If the client registered its own callback for graph order events,
505 if (client
->control
->graph_order_cbset
) {
506 client
->graph_order (client
->graph_order_arg
);
515 jack_handle_reorder (jack_client_t
*client
, jack_event_t
*event
)
517 char path
[PATH_MAX
+1];
519 DEBUG ("graph reorder\n");
521 if (client
->graph_wait_fd
>= 0) {
522 DEBUG ("closing graph_wait_fd==%d", client
->graph_wait_fd
);
523 close (client
->graph_wait_fd
);
524 client
->graph_wait_fd
= -1;
527 if (client
->graph_next_fd
>= 0) {
528 DEBUG ("closing graph_next_fd==%d", client
->graph_next_fd
);
529 close (client
->graph_next_fd
);
530 client
->graph_next_fd
= -1;
533 sprintf (path
, "%s-%" PRIu32
, client
->fifo_prefix
, event
->x
.n
);
535 if ((client
->graph_wait_fd
= open (path
, O_RDONLY
|O_NONBLOCK
)) < 0) {
536 jack_error ("cannot open specified fifo [%s] for reading (%s)",
537 path
, strerror (errno
));
540 DEBUG ("opened new graph_wait_fd %d (%s)", client
->graph_wait_fd
, path
);
542 sprintf (path
, "%s-%" PRIu32
, client
->fifo_prefix
, event
->x
.n
+1);
544 if ((client
->graph_next_fd
= open (path
, O_WRONLY
|O_NONBLOCK
)) < 0) {
545 jack_error ("cannot open specified fifo [%s] for writing (%s)",
546 path
, strerror (errno
));
550 client
->upstream_is_jackd
= event
->y
.n
;
553 DEBUG ("opened new graph_next_fd %d (%s) (upstream is jackd? %d)",
554 client
->graph_next_fd
, path
,
555 client
->upstream_is_jackd
);
557 /* If the client registered its own callback for graph order events,
561 if (client
->control
->graph_order_cbset
) {
562 client
->graph_order (client
->graph_order_arg
);
571 server_connect (const char *server_name
)
574 struct sockaddr_un addr
;
577 char server_dir
[PATH_MAX
+1] = "";
579 if ((fd
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0) {
580 jack_error ("cannot create client socket (%s)",
585 //JOQ: temporary debug message
586 //jack_info ("DEBUG: connecting to `%s' server", server_name);
588 addr
.sun_family
= AF_UNIX
;
589 snprintf (addr
.sun_path
, sizeof (addr
.sun_path
) - 1, "%s/jack_%d",
590 jack_server_dir (server_name
, server_dir
) , which
);
592 if (connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
601 server_event_connect (jack_client_t
*client
, const char *server_name
)
604 struct sockaddr_un addr
;
605 jack_client_connect_ack_request_t req
;
606 jack_client_connect_ack_result_t res
;
608 char server_dir
[PATH_MAX
+1] = "";
610 if ((fd
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0) {
611 jack_error ("cannot create client event socket (%s)",
616 addr
.sun_family
= AF_UNIX
;
617 snprintf (addr
.sun_path
, sizeof (addr
.sun_path
) - 1, "%s/jack_ack_0",
618 jack_server_dir (server_name
,server_dir
));
620 if (connect (fd
, (struct sockaddr
*) &addr
, sizeof (addr
)) < 0) {
621 jack_error ("cannot connect to jack server for events",
627 req
.client_id
= client
->control
->id
;
629 if (write (fd
, &req
, sizeof (req
)) != sizeof (req
)) {
630 jack_error ("cannot write event connect request to server (%s)",
636 if (read (fd
, &res
, sizeof (res
)) != sizeof (res
)) {
637 jack_error ("cannot read event connect result from server (%s)",
643 if (res
.status
!= 0) {
644 jack_error ("cannot connect to server for event stream (%s)",
653 /* Exec the JACK server in this process. Does not return. */
655 _start_server (const char *server_name
)
669 snprintf(filename
, 255, "%s/.jackdrc", getenv("HOME"));
670 fp
= fopen(filename
, "r");
673 fp
= fopen("/etc/jackdrc", "r");
675 /* if still not found, check old config name for backwards compatability */
677 fp
= fopen("/etc/jackd.conf", "r");
682 ret
= fscanf(fp
, "%s", buffer
);
683 while(ret
!= 0 && ret
!= EOF
) {
684 strcat(arguments
, buffer
);
685 strcat(arguments
, " ");
686 ret
= fscanf(fp
, "%s", buffer
);
688 if (strlen(arguments
) > 0) {
694 #if defined(USE_CAPABILITIES)
695 command
= JACK_LOCATION
"/jackstart";
696 strncpy(arguments
, JACK_LOCATION
"/jackstart -T -R -d "
697 JACK_DEFAULT_DRIVER
" -p 512", 255);
698 #else /* !USE_CAPABILITIES */
699 command
= JACK_LOCATION
"/jackd";
700 strncpy(arguments
, JACK_LOCATION
"/jackd -T -d "
701 JACK_DEFAULT_DRIVER
, 255);
702 #endif /* USE_CAPABILITIES */
704 result
= strcspn(arguments
, " ");
705 if ((command
= (char *) malloc(result
+1)) == NULL
) {
708 strncpy(command
, arguments
, result
);
709 command
[result
] = '\0';
712 if ((argv
= (char **) malloc (255)) == NULL
) {
717 /* insert -T and -nserver_name in front of arguments */
719 argv
[i
] = (char *) malloc(strlen ("-T") + 1);
720 strcpy (argv
[i
++], "-T");
722 size_t optlen
= strlen ("-n");
725 + strlen (server_name
) + 1);
727 strcpy (buf
+optlen
, server_name
);
732 result
= strcspn(arguments
+pos
, " ");
736 argv
[i
] = (char*)malloc(result
+1);
738 strncpy(argv
[i
], arguments
+pos
, result
);
739 argv
[i
][result
] = '\0';
747 fprintf (stderr
, "execing JACK using %s\n", command
);
748 for (_xx
= 0; argv
[_xx
]; ++_xx
) {
749 fprintf (stderr
, "\targv[%d] = %s\n", _xx
, argv
[_xx
]);
753 execv (command
, argv
);
756 /* If execv() succeeds, it does not return. There's no point
757 * in calling jack_error() here in the child process. */
758 fprintf (stderr
, "exec of JACK server (command = \"%s\") failed: %s\n", command
, strerror (errno
));
762 start_server (const char *server_name
, jack_options_t options
)
764 if ((options
& JackNoStartServer
)
765 || getenv("JACK_NO_START_SERVER")) {
769 /* The double fork() forces the server to become a child of
770 * init, which will always clean up zombie process state on
771 * termination. This even works in cases where the server
772 * terminates but this client does not.
774 * Since fork() is usually implemented using copy-on-write
775 * virtual memory tricks, the overhead of the second fork() is
776 * probably relatively small.
779 case 0: /* child process */
781 case 0: /* grandchild process */
782 _start_server(server_name
);
783 _exit (99); /* exec failed */
789 case -1: /* fork() error */
790 return 1; /* failed to start server */
793 /* only the original parent process goes here */
794 return 0; /* (probably) successful */
798 jack_request_client (ClientType type
,
799 const char* client_name
, jack_options_t options
,
800 jack_status_t
*status
, jack_varargs_t
*va
,
801 jack_client_connect_result_t
*res
, int *req_fd
)
803 jack_client_connect_request_t req
;
806 memset (&req
, 0, sizeof (req
));
807 req
.options
= options
;
809 if (strlen (client_name
) >= sizeof (req
.name
)) {
810 jack_error ("\"%s\" is too long to be used as a JACK client"
812 "Please use %lu characters or less.",
813 client_name
, sizeof (req
.name
));
818 && (strlen (va
->load_name
) > sizeof (req
.object_path
) - 1)) {
819 jack_error ("\"%s\" is too long to be used as a JACK shared"
821 "Please use %lu characters or less.",
822 va
->load_name
, sizeof (req
.object_path
) - 1);
827 && (strlen (va
->load_init
) > sizeof (req
.object_data
) - 1)) {
828 jack_error ("\"%s\" is too long to be used as a JACK shared"
829 " object data string.\n"
830 "Please use %lu characters or less.",
831 va
->load_init
, sizeof (req
.object_data
) - 1);
835 if ((*req_fd
= server_connect (va
->server_name
)) < 0) {
837 if (start_server(va
->server_name
, options
)) {
838 *status
|= (JackFailure
|JackServerFailed
);
845 *status
|= (JackFailure
|JackServerFailed
);
848 } while ((*req_fd
= server_connect (va
->server_name
)) < 0);
849 *status
|= JackServerStarted
;
852 /* format connection request */
854 req
.protocol_v
= jack_protocol_version
;
857 snprintf (req
.name
, sizeof (req
.name
),
859 snprintf (req
.object_path
, sizeof (req
.object_path
),
860 "%s", va
->load_name
);
861 snprintf (req
.object_data
, sizeof (req
.object_data
),
862 "%s", va
->load_init
);
864 if (write (*req_fd
, &req
, sizeof (req
)) != sizeof (req
)) {
865 jack_error ("cannot send request to jack server (%s)",
867 *status
|= (JackFailure
|JackServerError
);
871 if (read (*req_fd
, res
, sizeof (*res
)) != sizeof (*res
)) {
874 /* server shut the socket */
875 jack_error ("could not attach as client");
876 *status
|= (JackFailure
|JackServerError
);
880 if (errno
== ECONNRESET
) {
881 jack_error ("could not attach as JACK client "
882 "(server has exited)");
883 *status
|= (JackFailure
|JackServerError
);
887 jack_error ("cannot read response from jack server (%s)",
889 *status
|= (JackFailure
|JackServerError
);
893 *status
|= res
->status
; /* return server status bits */
895 if (*status
& JackFailure
) {
896 if (*status
& JackVersionError
) {
897 jack_error ("client linked with incompatible libjack"
900 jack_error ("could not attach to JACK server");
901 *status
|= JackServerError
;
927 jack_attach_port_segment (jack_client_t
*client
, jack_port_type_id_t ptid
)
929 /* Lookup, attach and register the port/buffer segments in use
933 if (client
->control
->type
!= ClientExternal
) {
934 jack_error("Only external clients need attach port segments");
938 /* make sure we have space to store the port
942 if (ptid
>= client
->n_port_types
) {
944 client
->port_segment
= (jack_shm_info_t
*)
945 realloc (client
->port_segment
,
946 sizeof (jack_shm_info_t
) * (ptid
+1));
948 memset (&client
->port_segment
[client
->n_port_types
],
950 sizeof (jack_shm_info_t
) *
951 (ptid
- client
->n_port_types
));
953 client
->n_port_types
= ptid
+ 1;
957 /* release any previous segment */
958 jack_release_shm (&client
->port_segment
[ptid
]);
961 /* get the index into the shm registry */
963 client
->port_segment
[ptid
].index
=
964 client
->engine
->port_types
[ptid
].shm_registry_index
;
966 /* attach the relevant segment */
968 if (jack_attach_shm (&client
->port_segment
[ptid
])) {
969 jack_error ("cannot attach port segment shared memory"
970 " (%s)", strerror (errno
));
978 jack_client_open_aux (const char *client_name
,
979 jack_options_t options
,
980 jack_status_t
*status
, va_list ap
)
982 /* optional arguments: */
983 jack_varargs_t va
; /* variable arguments */
987 jack_client_connect_result_t res
;
988 jack_client_t
*client
;
989 jack_port_type_id_t ptid
;
990 jack_status_t my_status
;
992 jack_messagebuffer_init ();
994 if (status
== NULL
) /* no status from caller? */
995 status
= &my_status
; /* use local status word */
998 /* validate parameters */
999 if ((options
& ~JackOpenOptions
)) {
1000 *status
|= (JackFailure
|JackInvalidOption
);
1001 jack_messagebuffer_exit ();
1005 /* parse variable arguments */
1006 jack_varargs_parse(options
, ap
, &va
);
1008 /* External clients need to know where the tmpdir used for
1009 communication with the server lives
1011 if (jack_get_tmpdir ()) {
1012 *status
|= JackFailure
;
1013 jack_messagebuffer_exit ();
1017 /* External clients need this initialized. It is already set
1018 * up in the server's address space for internal clients.
1022 if (jack_request_client (ClientExternal
, client_name
, options
, status
,
1023 &va
, &res
, &req_fd
)) {
1024 jack_messagebuffer_exit ();
1028 /* Allocate the jack_client_t structure in local memory.
1029 * Shared memory is not accessible yet. */
1030 client
= jack_client_alloc ();
1031 strcpy (client
->name
, res
.name
);
1032 strcpy (client
->fifo_prefix
, res
.fifo_prefix
);
1033 client
->request_fd
= req_fd
;
1034 client
->pollfd
[EVENT_POLL_INDEX
].events
=
1035 POLLIN
|POLLERR
|POLLHUP
|POLLNVAL
;
1036 #ifndef JACK_USE_MACH_THREADS
1037 client
->pollfd
[WAIT_POLL_INDEX
].events
=
1038 POLLIN
|POLLERR
|POLLHUP
|POLLNVAL
;
1041 /* Don't access shared memory until server connected. */
1042 if (jack_initialize_shm (va
.server_name
)) {
1043 jack_error ("Unable to initialize shared memory.");
1044 *status
|= (JackFailure
|JackShmFailure
);
1048 /* attach the engine control/info block */
1049 client
->engine_shm
.index
= res
.engine_shm_index
;
1050 if (jack_attach_shm (&client
->engine_shm
)) {
1051 jack_error ("cannot attached engine control shared memory"
1056 client
->engine
= (jack_control_t
*) jack_shm_addr (&client
->engine_shm
);
1058 /* initialize clock source as early as possible */
1059 jack_set_clock_source (client
->engine
->clock_source
);
1061 /* now attach the client control block */
1062 client
->control_shm
.index
= res
.client_shm_index
;
1063 if (jack_attach_shm (&client
->control_shm
)) {
1064 jack_error ("cannot attached client control shared memory"
1069 client
->control
= (jack_client_control_t
*)
1070 jack_shm_addr (&client
->control_shm
);
1072 /* Nobody else needs to access this shared memory any more, so
1073 * destroy it. Because we have it attached, it won't vanish
1074 * till we exit (and release it).
1076 jack_destroy_shm (&client
->control_shm
);
1078 client
->n_port_types
= client
->engine
->n_port_types
;
1079 if ((client
->port_segment
= (jack_shm_info_t
*) malloc (sizeof (jack_shm_info_t
) * client
->n_port_types
)) == NULL
) {
1083 for (ptid
= 0; ptid
< client
->n_port_types
; ++ptid
) {
1084 client
->port_segment
[ptid
].index
=
1085 client
->engine
->port_types
[ptid
].shm_registry_index
;
1086 client
->port_segment
[ptid
].attached_at
= MAP_FAILED
;
1087 jack_attach_port_segment (client
, ptid
);
1090 /* set up the client so that it does the right thing for an
1093 client
->deliver_request
= oop_client_deliver_request
;
1094 client
->deliver_arg
= client
;
1096 if ((ev_fd
= server_event_connect (client
, va
.server_name
)) < 0) {
1100 client
->event_fd
= ev_fd
;
1102 #ifdef JACK_USE_MACH_THREADS
1103 /* specific resources for server/client real-time thread
1105 client
->clienttask
= mach_task_self();
1107 if (task_get_bootstrap_port(client
->clienttask
, &client
->bp
)){
1108 jack_error ("Can't find bootstrap port");
1112 if (allocate_mach_clientport(client
, res
.portnum
) < 0) {
1113 jack_error("Can't allocate mach port");
1116 #endif /* JACK_USE_MACH_THREADS */
1120 jack_messagebuffer_exit ();
1122 if (client
->engine
) {
1123 jack_release_shm (&client
->engine_shm
);
1126 if (client
->control
) {
1127 jack_release_shm (&client
->control_shm
);
1128 client
->control
= 0;
1141 jack_client_t
* jack_client_open(const char* ext_client_name
, jack_options_t options
, jack_status_t
* status
, ...)
1144 va_start(ap
, status
);
1145 jack_client_t
* res
= jack_client_open_aux(ext_client_name
, options
, status
, ap
);
1151 jack_client_new (const char *client_name
)
1153 jack_options_t options
= JackUseExactName
;
1154 if (getenv("JACK_START_SERVER") == NULL
)
1155 options
|= JackNoStartServer
;
1156 return jack_client_open (client_name
, options
, NULL
);
1160 jack_get_client_name (jack_client_t
*client
)
1162 return client
->name
;
1166 jack_internal_client_new (const char *client_name
,
1167 const char *so_name
, const char *so_data
)
1169 jack_client_connect_result_t res
;
1172 jack_status_t status
;
1173 jack_options_t options
= JackUseExactName
;
1175 if (getenv("JACK_START_SERVER") == NULL
)
1176 options
|= JackNoStartServer
;
1178 jack_varargs_init (&va
);
1179 va
.load_name
= (char *) so_name
;
1180 va
.load_init
= (char *) so_data
;
1182 return jack_request_client (ClientInternal
, client_name
,
1183 options
, &status
, &va
, &res
, &req_fd
);
1187 jack_default_server_name (void)
1190 if ((server_name
= getenv("JACK_DEFAULT_SERVER")) == NULL
)
1191 server_name
= "default";
1195 /* returns the name of the per-user subdirectory of jack_tmpdir */
1197 jack_user_dir (void)
1199 static char user_dir
[PATH_MAX
+1] = "";
1201 /* format the path name on the first call */
1202 if (user_dir
[0] == '\0') {
1203 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
1204 snprintf (user_dir
, sizeof (user_dir
), "%s/jack",
1207 snprintf (user_dir
, sizeof (user_dir
), "%s/jack-%d",
1208 jack_tmpdir
, getuid ());
1215 /* returns the name of the per-server subdirectory of jack_user_dir() */
1217 jack_server_dir (const char *server_name
, char *server_dir
)
1219 /* format the path name into the suppled server_dir char array,
1220 * assuming that server_dir is at least as large as PATH_MAX+1 */
1222 snprintf (server_dir
, PATH_MAX
+1, "%s/%s",
1223 jack_user_dir (), server_name
);
1229 jack_internal_client_close (const char *client_name
)
1231 jack_client_connect_request_t req
;
1233 char *server_name
= jack_default_server_name ();
1236 snprintf (req
.name
, sizeof (req
.name
), "%s", client_name
);
1238 if ((fd
= server_connect (server_name
)) < 0) {
1242 if (write (fd
, &req
, sizeof (req
)) != sizeof(req
)) {
1243 jack_error ("cannot deliver ClientUnload request to JACK "
1247 /* no response to this request */
1254 jack_recompute_total_latencies (jack_client_t
* client
)
1256 jack_request_t request
;
1258 request
.type
= RecomputeTotalLatencies
;
1259 return jack_client_deliver_request (client
, &request
);
1263 jack_recompute_total_latency (jack_client_t
* client
, jack_port_t
* port
)
1265 jack_request_t request
;
1267 request
.type
= RecomputeTotalLatency
;
1268 request
.x
.port_info
.port_id
= port
->shared
->id
;
1269 return jack_client_deliver_request (client
, &request
);
1273 jack_set_freewheel (jack_client_t
* client
, int onoff
)
1275 jack_request_t request
;
1277 request
.type
= onoff
? FreeWheel
: StopFreeWheel
;
1278 return jack_client_deliver_request (client
, &request
);
1282 jack_start_freewheel (jack_client_t
* client
)
1284 jack_client_control_t
*control
= client
->control
;
1286 if (client
->engine
->real_time
) {
1287 #if JACK_USE_MACH_THREADS
1288 jack_drop_real_time_scheduling (client
->process_thread
);
1290 jack_drop_real_time_scheduling (client
->thread
);
1294 if (control
->freewheel_cb_cbset
) {
1295 client
->freewheel_cb (1, client
->freewheel_arg
);
1300 jack_stop_freewheel (jack_client_t
* client
)
1302 jack_client_control_t
*control
= client
->control
;
1304 if (client
->engine
->real_time
) {
1305 #if JACK_USE_MACH_THREADS
1306 jack_acquire_real_time_scheduling (client
->process_thread
,
1307 client
->engine
->client_priority
);
1309 jack_acquire_real_time_scheduling (client
->thread
,
1310 client
->engine
->client_priority
);
1314 if (control
->freewheel_cb_cbset
) {
1315 client
->freewheel_cb (0, client
->freewheel_arg
);
1320 jack_client_thread_suicide (jack_client_t
* client
)
1322 if (client
->on_info_shutdown
) {
1323 jack_error ("zombified - calling shutdown handler");
1324 client
->on_info_shutdown (JackClientZombie
, "Zombified", client
->on_info_shutdown_arg
);
1325 } else if (client
->on_shutdown
) {
1326 jack_error ("zombified - calling shutdown handler");
1327 client
->on_shutdown (client
->on_shutdown_arg
);
1329 jack_error ("jack_client_thread zombified - exiting from JACK");
1330 jack_client_close_aux (client
);
1331 /* Need a fix : possibly make client crash if
1332 * zombified without shutdown handler
1341 jack_client_process_events (jack_client_t
* client
)
1345 jack_client_control_t
*control
= client
->control
;
1349 DEBUG ("process events");
1351 if (client
->pollfd
[EVENT_POLL_INDEX
].revents
& POLLIN
) {
1353 DEBUG ("client receives an event, "
1354 "now reading on event fd");
1356 /* server has sent us an event. process the
1357 * event and reply */
1359 if (read (client
->event_fd
, &event
, sizeof (event
))
1360 != sizeof (event
)) {
1361 jack_error ("cannot read server event (%s)",
1368 switch (event
.type
) {
1369 case PortRegistered
:
1370 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
1372 if (port
->shared
->id
== event
.x
.port_id
) { // Found port, update port type
1373 port
->type_info
= &client
->engine
->port_types
[port
->shared
->ptype_id
];
1376 if (control
->port_register_cbset
) {
1377 client
->port_register
1378 (event
.x
.port_id
, TRUE
,
1379 client
->port_register_arg
);
1383 case PortUnregistered
:
1384 if (control
->port_register_cbset
) {
1385 client
->port_register
1386 (event
.x
.port_id
, FALSE
,
1387 client
->port_register_arg
);
1391 case ClientRegistered
:
1392 if (control
->client_register_cbset
) {
1393 client
->client_register
1394 (event
.x
.name
, TRUE
,
1395 client
->client_register_arg
);
1399 case ClientUnregistered
:
1400 if (control
->client_register_cbset
) {
1401 client
->client_register
1402 (event
.x
.name
, FALSE
,
1403 client
->client_register_arg
);
1407 case GraphReordered
:
1408 status
= jack_handle_reorder (client
, &event
);
1412 case PortDisconnected
:
1413 status
= jack_client_handle_port_connection
1417 case BufferSizeChange
:
1418 jack_client_invalidate_port_buffers (client
);
1419 if (control
->bufsize_cbset
) {
1420 status
= client
->bufsize
1422 client
->bufsize_arg
);
1426 case SampleRateChange
:
1427 if (control
->srate_cbset
) {
1428 status
= client
->srate
1435 if (control
->xrun_cbset
) {
1436 status
= client
->xrun
1441 case AttachPortSegment
:
1442 jack_attach_port_segment (client
, event
.y
.ptid
);
1445 case StartFreewheel
:
1446 jack_start_freewheel (client
);
1450 jack_stop_freewheel (client
);
1454 DEBUG ("client has dealt with the event, writing "
1455 "response on event fd");
1457 if (write (client
->event_fd
, &status
, sizeof (status
))
1458 != sizeof (status
)) {
1459 jack_error ("cannot send event response to "
1460 "engine (%s)", strerror (errno
));
1469 jack_client_core_wait (jack_client_t
* client
)
1471 jack_client_control_t
*control
= client
->control
;
1473 DEBUG ("client polling on %s", client
->pollmax
== 2 ?
1474 "event_fd and graph_wait_fd..." :
1478 if (poll (client
->pollfd
, client
->pollmax
, 1000) < 0) {
1479 if (errno
== EINTR
) {
1482 jack_error ("poll failed in client (%s)",
1487 pthread_testcancel();
1489 #ifndef JACK_USE_MACH_THREADS
1491 /* get an accurate timestamp on waking from poll for a
1495 if (client
->graph_wait_fd
>= 0
1496 && client
->pollfd
[WAIT_POLL_INDEX
].revents
& POLLIN
) {
1497 control
->awake_at
= jack_get_microseconds();
1500 DEBUG ("pfd[EVENT].revents = 0x%x pfd[WAIT].revents = 0x%x",
1501 client
->pollfd
[EVENT_POLL_INDEX
].revents
,
1502 client
->pollfd
[WAIT_POLL_INDEX
].revents
);
1504 if (client
->graph_wait_fd
>= 0 &&
1505 (client
->pollfd
[WAIT_POLL_INDEX
].revents
& ~POLLIN
)) {
1507 /* our upstream "wait" connection
1508 closed, which either means that
1509 an intermediate client exited, or
1510 jackd exited, or jackd zombified
1513 we can discover the zombification
1514 via client->control->dead, but
1515 the other two possibilities are
1516 impossible to identify just from
1517 this situation. so we have to
1518 check what we are connected to,
1519 and act accordingly.
1522 if (client
->upstream_is_jackd
) {
1526 DEBUG ("WE PUNT\n");
1527 /* don't poll on the wait fd
1528 * again until we get a
1529 * GraphReordered event.
1532 client
->graph_wait_fd
= -1;
1533 client
->pollmax
= 1;
1538 if (jack_client_process_events (client
)) {
1539 DEBUG ("event processing failed\n");
1543 if (client
->graph_wait_fd
>= 0 &&
1544 (client
->pollfd
[WAIT_POLL_INDEX
].revents
& POLLIN
)) {
1545 DEBUG ("time to run process()\n");
1550 if (control
->dead
|| client
->pollfd
[EVENT_POLL_INDEX
].revents
& ~POLLIN
) {
1551 DEBUG ("client appears dead or event pollfd has error status\n");
1559 jack_wake_next_client (jack_client_t
* client
)
1561 struct pollfd pfds
[1];
1565 if (write (client
->graph_next_fd
, &c
, sizeof (c
))
1567 DEBUG("cannot write byte to fd %d", client
->graph_next_fd
);
1568 jack_error ("cannot continue execution of the "
1569 "processing graph (%s)",
1574 DEBUG ("client sent message to next stage by %" PRIu64
"",
1575 jack_get_microseconds());
1577 DEBUG("reading cleanup byte from pipe %d\n", client
->graph_wait_fd
);
1579 /* "upstream client went away? readability is checked in
1580 * jack_client_core_wait(), but that's almost a whole cycle
1581 * before we get here.
1584 if (client
->graph_wait_fd
>= 0) {
1585 pfds
[0].fd
= client
->graph_wait_fd
;
1586 pfds
[0].events
= POLLIN
;
1588 /* 0 timeout, don't actually wait */
1589 pret
= poll(pfds
, 1, 0);
1592 if (pret
> 0 && (pfds
[0].revents
& POLLIN
)) {
1593 if (read (client
->graph_wait_fd
, &c
, sizeof (c
))
1595 jack_error ("cannot complete execution of the "
1596 "processing graph (%s)", strerror(errno
));
1600 DEBUG("cleanup byte from pipe %d not available?\n",
1601 client
->graph_wait_fd
);
1607 static jack_nframes_t
1608 jack_thread_first_wait (jack_client_t
* client
)
1610 if (jack_client_core_wait (client
)) {
1613 return client
->control
->nframes
;
1617 jack_thread_wait (jack_client_t
* client
, int status
)
1619 client
->control
->last_status
= status
;
1621 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1623 /* housekeeping/cleanup after data processing */
1625 if (status
== 0 && client
->control
->timebase_cb_cbset
) {
1626 jack_call_timebase_master (client
);
1629 /* end preemption checking */
1630 CHECK_PREEMPTION (client
->engine
, FALSE
);
1632 client
->control
->finished_at
= jack_get_microseconds();
1634 /* wake the next client in the chain (could be the server),
1635 and check if we were killed during the process
1639 if (jack_wake_next_client (client
)) {
1640 DEBUG("client cannot wake next, or is dead\n");
1644 if (status
|| client
->control
->dead
|| !client
->engine
->engine_ok
) {
1648 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1650 if (jack_client_core_wait (client
)) {
1654 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1656 /* Time to do data processing */
1658 client
->control
->state
= Running
;
1660 /* begin preemption checking */
1661 CHECK_PREEMPTION (client
->engine
, TRUE
);
1663 if (client
->control
->sync_cb_cbset
)
1664 jack_call_sync_client (client
);
1666 return client
->control
->nframes
;
1669 jack_nframes_t
jack_cycle_wait (jack_client_t
* client
)
1671 /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */
1673 if (jack_client_core_wait (client
)) {
1677 /* SECTION THREE: START NEXT DATA PROCESSING TIME */
1679 /* Time to do data processing */
1681 client
->control
->state
= Running
;
1683 /* begin preemption checking */
1684 CHECK_PREEMPTION (client
->engine
, TRUE
);
1686 if (client
->control
->sync_cb_cbset
)
1687 jack_call_sync_client (client
);
1689 return client
->control
->nframes
;
1692 void jack_cycle_signal(jack_client_t
* client
, int status
)
1694 client
->control
->last_status
= status
;
1696 /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */
1698 /* housekeeping/cleanup after data processing */
1700 if (status
== 0 && client
->control
->timebase_cb_cbset
) {
1701 jack_call_timebase_master (client
);
1704 /* end preemption checking */
1705 CHECK_PREEMPTION (client
->engine
, FALSE
);
1707 client
->control
->finished_at
= jack_get_microseconds();
1709 /* wake the next client in the chain (could be the server),
1710 and check if we were killed during the process
1714 if (jack_wake_next_client (client
)) {
1715 DEBUG("client cannot wake next, or is dead\n");
1716 jack_client_thread_suicide (client
);
1720 if (status
|| client
->control
->dead
|| !client
->engine
->engine_ok
) {
1721 jack_client_thread_suicide (client
);
1727 jack_client_thread_aux (void *arg
)
1729 jack_client_t
*client
= (jack_client_t
*) arg
;
1730 jack_client_control_t
*control
= client
->control
;
1732 pthread_mutex_lock (&client_lock
);
1733 client
->thread_ok
= TRUE
;
1734 client
->thread_id
= pthread_self();
1735 pthread_cond_signal (&client_ready
);
1736 pthread_mutex_unlock (&client_lock
);
1738 control
->pid
= getpid();
1739 control
->pgrp
= getpgrp();
1741 DEBUG ("client thread is now running");
1743 if (control
->thread_init_cbset
) {
1744 DEBUG ("calling client thread init callback");
1745 client
->thread_init (client
->thread_init_arg
);
1748 /* wait for first wakeup from server */
1750 if (jack_thread_first_wait (client
) == control
->nframes
) {
1752 /* now run till we're done */
1754 if (control
->process_cbset
) {
1756 /* run process callback, then wait... ad-infinitum */
1759 DEBUG("client calls process()");
1760 int status
= (client
->process (control
->nframes
,
1761 client
->process_arg
) ==
1763 control
->state
= Finished
;
1764 DEBUG("client leaves process(), re-enters wait");
1765 if (!jack_thread_wait (client
, status
)) {
1768 DEBUG("client done with wait");
1772 /* no process handling but still need to process events */
1773 while (jack_thread_wait (client
, 0) == control
->nframes
)
1778 jack_client_thread_suicide (client
);
1782 jack_client_thread (void *arg
)
1784 jack_client_t
*client
= (jack_client_t
*) arg
;
1785 jack_client_control_t
*control
= client
->control
;
1787 if (client
->control
->thread_cb_cbset
) {
1789 pthread_mutex_lock (&client_lock
);
1790 client
->thread_ok
= TRUE
;
1791 client
->thread_id
= pthread_self();
1792 pthread_cond_signal (&client_ready
);
1793 pthread_mutex_unlock (&client_lock
);
1795 control
->pid
= getpid();
1796 control
->pgrp
= getpgrp();
1798 client
->thread_cb(client
->thread_cb_arg
);
1799 jack_client_thread_suicide(client
);
1801 jack_client_thread_aux(arg
);
1808 #ifdef JACK_USE_MACH_THREADS
1809 /* real-time thread : separated from the normal client thread, it will
1810 * communicate with the server using fast mach RPC mechanism */
1813 jack_client_process_thread (void *arg
)
1815 jack_client_t
*client
= (jack_client_t
*) arg
;
1816 jack_client_control_t
*control
= client
->control
;
1819 if (client
->control
->thread_init_cbset
) {
1820 /* this means that the init callback will be called twice -taybin*/
1821 DEBUG ("calling client thread init callback");
1822 client
->thread_init (client
->thread_init_arg
);
1825 client
->control
->pid
= getpid();
1826 DEBUG ("client process thread is now running");
1828 client
->rt_thread_ok
= TRUE
;
1832 if (jack_client_suspend(client
) < 0) {
1833 jack_error ("jack_client_process_thread :resume error");
1837 control
->awake_at
= jack_get_microseconds();
1839 DEBUG ("client resumed");
1841 control
->state
= Running
;
1843 if (control
->sync_cb_cbset
)
1844 jack_call_sync_client (client
);
1846 if (control
->process_cbset
) {
1847 if (client
->process (control
->nframes
,
1848 client
->process_arg
) == 0) {
1849 control
->state
= Finished
;
1852 control
->state
= Finished
;
1855 if (control
->timebase_cb_cbset
)
1856 jack_call_timebase_master (client
);
1858 control
->finished_at
= jack_get_microseconds();
1860 DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
1861 control
->finished_at
,
1862 ((float)(control
->finished_at
- control
->awake_at
)));
1864 /* check if we were killed during the process cycle
1867 if (client
->control
->dead
) {
1868 jack_error ("jack_client_process_thread: "
1869 "client->control->dead");
1873 DEBUG("process cycle fully complete\n");
1877 return (void *) ((intptr_t)err
);
1881 jack_error ("jack_client_process_thread : zombified");
1883 client
->rt_thread_ok
= FALSE
;
1885 if (client
->on_info_shutdown
) {
1886 jack_error ("zombified - calling shutdown handler");
1887 client
->on_info_shutdown (JackClientZombie
, "Zombified", client
->on_info_shutdown_arg
);
1888 } else if (client
->on_shutdown
) {
1889 jack_error ("zombified - calling shutdown handler");
1890 client
->on_shutdown (client
->on_shutdown_arg
);
1892 jack_error ("jack_client_process_thread zombified - exiting from JACK");
1893 /* Need a fix : possibly make client crash if
1894 * zombified without shutdown handler */
1895 jack_client_close_aux (client
);
1902 #endif /* JACK_USE_MACH_THREADS */
1905 jack_start_thread (jack_client_t
*client
)
1907 if (client
->engine
->real_time
) {
1910 if (client
->engine
->do_mlock
1911 && (mlockall (MCL_CURRENT
| MCL_FUTURE
) != 0)) {
1912 jack_error ("cannot lock down memory for RT thread "
1913 "(%s)", strerror (errno
));
1917 #endif /* ENSURE_MLOCK */
1920 if (client
->engine
->do_munlock
) {
1923 #endif /* USE_MLOCK */
1926 #ifdef JACK_USE_MACH_THREADS
1927 /* Stephane Letz : letz@grame.fr
1928 On MacOSX, the normal thread does not need to be real-time.
1930 if (jack_client_create_thread (client
,
1932 client
->engine
->client_priority
,
1934 jack_client_thread
, client
)) {
1938 if (jack_client_create_thread (client
,
1940 client
->engine
->client_priority
,
1941 client
->engine
->real_time
,
1942 jack_client_thread
, client
)) {
1948 #ifdef JACK_USE_MACH_THREADS
1950 /* a secondary thread that runs the process callback and uses
1951 ultra-fast Mach primitives for inter-thread signalling.
1953 XXX in a properly structured JACK, there would be no
1954 need for this, because we would have client wake up
1955 methods that encapsulated the underlying mechanism
1960 if (jack_client_create_thread(client
,
1961 &client
->process_thread
,
1962 client
->engine
->client_priority
,
1963 client
->engine
->real_time
,
1964 jack_client_process_thread
, client
)) {
1967 #endif /* JACK_USE_MACH_THREADS */
1973 jack_activate (jack_client_t
*client
)
1977 /* we need to scribble on our stack to ensure that its memory
1978 * pages are actually mapped (more important for mlockall(2)
1979 * usage in jack_start_thread())
1982 char buf
[JACK_THREAD_STACK_TOUCH
];
1985 for (i
= 0; i
< JACK_THREAD_STACK_TOUCH
; i
++) {
1986 buf
[i
] = (char) (i
& 0xff);
1989 if (client
->control
->type
== ClientInternal
||
1990 client
->control
->type
== ClientDriver
) {
1994 /* get the pid of the client process to pass it to engine */
1996 client
->control
->pid
= getpid ();
1998 #ifdef USE_CAPABILITIES
2000 if (client
->engine
->has_capabilities
!= 0 &&
2001 client
->control
->pid
!= 0 && client
->engine
->real_time
!= 0) {
2003 /* we need to ask the engine for realtime capabilities
2004 before trying to start the realtime thread
2007 req
.type
= SetClientCapabilities
;
2008 req
.x
.client_id
= client
->control
->id
;
2009 req
.x
.cap_pid
= client
->control
->pid
;
2011 jack_client_deliver_request (client
, &req
);
2015 /* what to do? engine is running realtime, it
2016 is using capabilities and has them
2017 (otherwise we would not get an error
2018 return) but for some reason it could not
2019 give the client the required capabilities.
2020 For now, leave the client so that it
2021 still runs, albeit non-realtime.
2024 jack_error ("could not receive realtime capabilities, "
2025 "client will run non-realtime");
2028 #endif /* USE_CAPABILITIES */
2030 if (client
->first_active
) {
2032 pthread_mutex_init (&client_lock
, NULL
);
2033 pthread_cond_init (&client_ready
, NULL
);
2035 pthread_mutex_lock (&client_lock
);
2037 if (jack_start_thread (client
)) {
2038 pthread_mutex_unlock (&client_lock
);
2042 pthread_cond_wait (&client_ready
, &client_lock
);
2043 pthread_mutex_unlock (&client_lock
);
2045 if (!client
->thread_ok
) {
2046 jack_error ("could not start client thread");
2050 client
->first_active
= FALSE
;
2055 req
.type
= ActivateClient
;
2056 req
.x
.client_id
= client
->control
->id
;
2058 return jack_client_deliver_request (client
, &req
);
2062 jack_deactivate_aux (jack_client_t
*client
)
2065 int rc
= ESRCH
; /* already shut down */
2067 if (client
&& client
->control
) { /* not shut down? */
2069 if (client
->control
->active
) { /* still active? */
2070 req
.type
= DeactivateClient
;
2071 req
.x
.client_id
= client
->control
->id
;
2072 rc
= jack_client_deliver_request (client
, &req
);
2079 jack_deactivate (jack_client_t
*client
)
2081 return jack_deactivate_aux(client
);
2085 jack_client_close_aux (jack_client_t
*client
)
2091 rc
= jack_deactivate_aux (client
);
2092 if (rc
== ESRCH
) { /* already shut down? */
2096 if (client
->control
->type
== ClientExternal
) {
2098 #if JACK_USE_MACH_THREADS
2099 if (client
->rt_thread_ok
) {
2100 // MacOSX pthread_cancel not implemented in
2102 mach_port_t machThread
=
2103 pthread_mach_thread_np (client
->process_thread
);
2104 thread_terminate (machThread
);
2108 /* stop the thread that communicates with the jack
2109 * server, only if it was actually running
2112 if (client
->thread_ok
){
2113 pthread_cancel (client
->thread
);
2114 pthread_join (client
->thread
, &status
);
2117 if (client
->control
) {
2118 jack_release_shm (&client
->control_shm
);
2119 client
->control
= NULL
;
2121 if (client
->engine
) {
2122 jack_release_shm (&client
->engine_shm
);
2123 client
->engine
= NULL
;
2126 if (client
->port_segment
) {
2127 jack_port_type_id_t ptid
;
2128 for (ptid
= 0; ptid
< client
->n_port_types
; ++ptid
) {
2129 jack_release_shm (&client
->port_segment
[ptid
]);
2131 free (client
->port_segment
);
2132 client
->port_segment
= NULL
;
2135 #ifndef JACK_USE_MACH_THREADS
2136 if (client
->graph_wait_fd
>= 0) {
2137 close (client
->graph_wait_fd
);
2140 if (client
->graph_next_fd
>= 0) {
2141 close (client
->graph_next_fd
);
2145 close (client
->event_fd
);
2147 if (shutdown (client
->request_fd
, SHUT_RDWR
)) {
2148 jack_error ("could not shutdown client request socket");
2151 close (client
->request_fd
);
2155 for (node
= client
->ports
; node
; node
= jack_slist_next (node
)) {
2158 jack_slist_free (client
->ports
);
2159 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
2162 jack_slist_free (client
->ports_ext
);
2163 jack_client_free (client
);
2164 jack_messagebuffer_exit ();
2170 jack_client_close (jack_client_t
*client
)
2172 return jack_client_close_aux(client
);
2176 jack_is_realtime (jack_client_t
*client
)
2178 return client
->engine
->real_time
;
2182 jack_get_buffer_size (jack_client_t
*client
)
2184 return client
->engine
->buffer_size
;
2188 jack_set_buffer_size (jack_client_t
*client
, jack_nframes_t nframes
)
2190 #ifdef DO_BUFFER_RESIZE
2193 req
.type
= SetBufferSize
;
2194 req
.x
.nframes
= nframes
;
2196 return jack_client_deliver_request (client
, &req
);
2200 #endif /* DO_BUFFER_RESIZE */
2204 jack_connect (jack_client_t
*client
, const char *source_port
,
2205 const char *destination_port
)
2209 req
.type
= ConnectPorts
;
2211 snprintf (req
.x
.connect
.source_port
,
2212 sizeof (req
.x
.connect
.source_port
), "%s", source_port
);
2213 snprintf (req
.x
.connect
.destination_port
,
2214 sizeof (req
.x
.connect
.destination_port
),
2215 "%s", destination_port
);
2217 return jack_client_deliver_request (client
, &req
);
2221 jack_port_disconnect (jack_client_t
*client
, jack_port_t
*port
)
2225 pthread_mutex_lock (&port
->connection_lock
);
2227 if (port
->connections
== NULL
) {
2228 pthread_mutex_unlock (&port
->connection_lock
);
2232 pthread_mutex_unlock (&port
->connection_lock
);
2234 req
.type
= DisconnectPort
;
2235 req
.x
.port_info
.port_id
= port
->shared
->id
;
2237 return jack_client_deliver_request (client
, &req
);
2241 jack_disconnect (jack_client_t
*client
, const char *source_port
,
2242 const char *destination_port
)
2246 req
.type
= DisconnectPorts
;
2248 snprintf (req
.x
.connect
.source_port
,
2249 sizeof (req
.x
.connect
.source_port
), "%s", source_port
);
2250 snprintf (req
.x
.connect
.destination_port
,
2251 sizeof (req
.x
.connect
.destination_port
),
2252 "%s", destination_port
);
2254 return jack_client_deliver_request (client
, &req
);
2258 jack_set_error_function (void (*func
) (const char *))
2260 jack_error_callback
= func
;
2264 jack_set_info_function (void (*func
) (const char *))
2266 jack_info_callback
= func
;
2270 jack_set_graph_order_callback (jack_client_t
*client
,
2271 JackGraphOrderCallback callback
, void *arg
)
2273 if (client
->control
->active
) {
2274 jack_error ("You cannot set callbacks on an active client.");
2277 client
->graph_order
= callback
;
2278 client
->graph_order_arg
= arg
;
2279 client
->control
->graph_order_cbset
= (callback
!= NULL
);
2283 int jack_set_xrun_callback (jack_client_t
*client
,
2284 JackXRunCallback callback
, void *arg
)
2286 if (client
->control
->active
) {
2287 jack_error ("You cannot set callbacks on an active client.");
2291 client
->xrun
= callback
;
2292 client
->xrun_arg
= arg
;
2293 client
->control
->xrun_cbset
= (callback
!= NULL
);
2298 jack_set_process_callback (jack_client_t
*client
,
2299 JackProcessCallback callback
, void *arg
)
2302 if (client
->control
->active
) {
2303 jack_error ("You cannot set callbacks on an active client.");
2307 if (client
->control
->thread_cb_cbset
) {
2308 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
2312 client
->process_arg
= arg
;
2313 client
->process
= callback
;
2314 client
->control
->process_cbset
= (callback
!= NULL
);
2319 jack_set_thread_init_callback (jack_client_t
*client
,
2320 JackThreadInitCallback callback
, void *arg
)
2323 if (client
->control
->active
) {
2324 jack_error ("You cannot set callbacks on an active client.");
2327 client
->thread_init_arg
= arg
;
2328 client
->thread_init
= callback
;
2329 client
->control
->thread_init_cbset
= (callback
!= NULL
);
2331 /* make sure that the message buffer thread is initialized too */
2333 jack_messagebuffer_thread_init (callback
, arg
);
2339 jack_set_freewheel_callback (jack_client_t
*client
,
2340 JackFreewheelCallback callback
, void *arg
)
2342 if (client
->control
->active
) {
2343 jack_error ("You cannot set callbacks on an active client.");
2346 client
->freewheel_arg
= arg
;
2347 client
->freewheel_cb
= callback
;
2348 client
->control
->freewheel_cb_cbset
= (callback
!= NULL
);
2353 jack_set_buffer_size_callback (jack_client_t
*client
,
2354 JackBufferSizeCallback callback
, void *arg
)
2356 client
->bufsize_arg
= arg
;
2357 client
->bufsize
= callback
;
2358 client
->control
->bufsize_cbset
= (callback
!= NULL
);
2363 jack_set_port_registration_callback(jack_client_t
*client
,
2364 JackPortRegistrationCallback callback
,
2367 if (client
->control
->active
) {
2368 jack_error ("You cannot set callbacks on an active client.");
2371 client
->port_register_arg
= arg
;
2372 client
->port_register
= callback
;
2373 client
->control
->port_register_cbset
= (callback
!= NULL
);
2378 jack_set_port_connect_callback(jack_client_t
*client
,
2379 JackPortConnectCallback callback
,
2382 if (client
->control
->active
) {
2383 jack_error ("You cannot set callbacks on an active client.");
2386 client
->port_connect_arg
= arg
;
2387 client
->port_connect
= callback
;
2388 client
->control
->port_connect_cbset
= (callback
!= NULL
);
2393 jack_set_client_registration_callback(jack_client_t
*client
,
2394 JackClientRegistrationCallback callback
,
2397 if (client
->control
->active
) {
2398 jack_error ("You cannot set callbacks on an active client.");
2401 client
->client_register_arg
= arg
;
2402 client
->client_register
= callback
;
2403 client
->control
->client_register_cbset
= (callback
!= NULL
);
2408 jack_set_process_thread(jack_client_t
* client
, JackThreadCallback callback
, void *arg
)
2410 if (client
->control
->active
) {
2411 jack_error ("You cannot set callbacks on an active client.");
2415 if (client
->control
->process_cbset
) {
2416 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
2420 client
->thread_cb_arg
= arg
;
2421 client
->thread_cb
= callback
;
2422 client
->control
->thread_cb_cbset
= (callback
!= NULL
);
2427 jack_get_process_done_fd (jack_client_t
*client
)
2429 return client
->graph_next_fd
;
2433 jack_on_shutdown (jack_client_t
*client
, void (*function
)(void *arg
), void *arg
)
2435 client
->on_shutdown
= function
;
2436 client
->on_shutdown_arg
= arg
;
2440 jack_on_info_shutdown (jack_client_t
*client
, void (*function
)(jack_status_t
, const char*, void *arg
), void *arg
)
2442 client
->on_info_shutdown
= function
;
2443 client
->on_info_shutdown_arg
= arg
;
2447 jack_get_ports (jack_client_t
*client
,
2448 const char *port_name_pattern
,
2449 const char *type_name_pattern
,
2450 unsigned long flags
)
2452 jack_control_t
*engine
;
2453 const char **matching_ports
;
2454 unsigned long match_cnt
;
2455 jack_port_shared_t
*psp
;
2461 engine
= client
->engine
;
2463 if (port_name_pattern
&& port_name_pattern
[0]) {
2464 regcomp (&port_regex
, port_name_pattern
,
2465 REG_EXTENDED
|REG_NOSUB
);
2467 if (type_name_pattern
&& type_name_pattern
[0]) {
2468 regcomp (&type_regex
, type_name_pattern
,
2469 REG_EXTENDED
|REG_NOSUB
);
2472 psp
= engine
->ports
;
2475 if ((matching_ports
= (const char **) malloc (sizeof (char *) * engine
->port_max
)) == NULL
) {
2479 for (i
= 0; i
< engine
->port_max
; i
++) {
2482 if (!psp
[i
].in_use
) {
2487 if ((psp
[i
].flags
& flags
) != flags
) {
2492 if (matching
&& port_name_pattern
&& port_name_pattern
[0]) {
2493 if (regexec (&port_regex
, psp
[i
].name
, 0, NULL
, 0)) {
2498 if (matching
&& type_name_pattern
&& type_name_pattern
[0]) {
2499 jack_port_type_id_t ptid
= psp
[i
].ptype_id
;
2500 if (regexec (&type_regex
,
2501 engine
->port_types
[ptid
].type_name
,
2508 matching_ports
[match_cnt
++] = psp
[i
].name
;
2511 if (port_name_pattern
&& port_name_pattern
[0]) {
2512 regfree (&port_regex
);
2514 if (type_name_pattern
&& type_name_pattern
[0]) {
2515 regfree (&type_regex
);
2518 matching_ports
[match_cnt
] = 0;
2520 if (match_cnt
== 0) {
2521 free (matching_ports
);
2525 return matching_ports
;
2529 jack_cpu_load (jack_client_t
*client
)
2531 return client
->engine
->cpu_load
;
2535 jack_get_xrun_delayed_usecs (jack_client_t
*client
)
2537 return client
->engine
->xrun_delayed_usecs
;
2541 jack_get_max_delayed_usecs (jack_client_t
*client
)
2543 return client
->engine
->max_delayed_usecs
;
2547 jack_reset_max_delayed_usecs (jack_client_t
*client
)
2549 client
->engine
->max_delayed_usecs
= 0.0f
;
2553 jack_client_thread_id (jack_client_t
*client
)
2555 return client
->thread_id
;
2559 jack_client_name_size(void)
2561 return JACK_CLIENT_NAME_SIZE
;
2565 jack_port_name_size(void)
2567 return JACK_PORT_NAME_SIZE
;
2571 jack_port_type_size(void)
2573 return JACK_PORT_TYPE_SIZE
;
2577 jack_free (void* ptr
)