37 #include "driver_interface.h"
38 #include "JackError.h"
39 #include "JackServer.h"
41 #include "JackTools.h"
42 #include "JackControlAPI.h"
43 #include "JackLockedEngine.h"
44 #include "JackConstants.h"
45 #include "JackDriverLoader.h"
46 #include "JackServerGlobals.h"
118 const char * short_description;
119 const char * long_description;
120 jackctl_param_type_t type;
135 jackctl_add_parameter(
136 JSList ** parameters_list_ptr_ptr,
138 const char * short_description,
139 const char * long_description,
140 jackctl_param_type_t type,
149 if (parameter_ptr == NULL)
151 jack_error(
"Cannot allocate memory for jackctl_parameter structure.");
155 parameter_ptr->name = name;
156 parameter_ptr->short_description = short_description;
157 parameter_ptr->long_description = long_description;
158 parameter_ptr->type = type;
159 parameter_ptr->is_set =
false;
161 if (value_ptr == NULL)
163 value_ptr = ¶meter_ptr->value;
166 if (default_value_ptr == NULL)
168 default_value_ptr = ¶meter_ptr->default_value;
171 parameter_ptr->value_ptr = value_ptr;
172 parameter_ptr->default_value_ptr = default_value_ptr;
174 *value_ptr = *default_value_ptr = value;
176 parameter_ptr->driver_ptr = NULL;
177 parameter_ptr->driver_parameter_ptr = NULL;
178 parameter_ptr->id = 0;
179 parameter_ptr->constraint_ptr = constraint_ptr;
181 *parameters_list_ptr_ptr = jack_slist_append(*parameters_list_ptr_ptr, parameter_ptr);
183 return parameter_ptr;
191 jackctl_free_driver_parameters(
196 while (driver_ptr->parameters)
198 next_node_ptr = driver_ptr->parameters->next;
199 free(driver_ptr->parameters->data);
200 free(driver_ptr->parameters);
201 driver_ptr->parameters = next_node_ptr;
204 while (driver_ptr->set_parameters)
206 next_node_ptr = driver_ptr->set_parameters->next;
207 free(driver_ptr->set_parameters->data);
208 free(driver_ptr->set_parameters);
209 driver_ptr->set_parameters = next_node_ptr;
215 jackctl_add_driver_parameters(
221 jackctl_param_type_t jackctl_type;
225 for (i = 0 ; i < driver_ptr->desc_ptr->
nparams ; i++)
227 descriptor_ptr = driver_ptr->desc_ptr->
params + i;
229 switch (descriptor_ptr->
type)
231 case JackDriverParamInt:
233 jackctl_value.i = descriptor_ptr->
value.i;
235 case JackDriverParamUInt:
237 jackctl_value.ui = descriptor_ptr->
value.ui;
239 case JackDriverParamChar:
241 jackctl_value.c = descriptor_ptr->
value.c;
243 case JackDriverParamString:
245 strcpy(jackctl_value.str, descriptor_ptr->
value.str);
247 case JackDriverParamBool:
249 jackctl_value.b = descriptor_ptr->
value.i;
252 jack_error(
"unknown driver parameter type %i", (
int)descriptor_ptr->
type);
257 parameter_ptr = jackctl_add_parameter(
258 &driver_ptr->parameters,
259 descriptor_ptr->
name,
268 if (parameter_ptr == NULL)
273 parameter_ptr->driver_ptr = driver_ptr;
274 parameter_ptr->id = descriptor_ptr->
character;
280 jackctl_free_driver_parameters(driver_ptr);
286 jackctl_drivers_load(
291 JSList *descriptor_node_ptr;
293 descriptor_node_ptr = jack_drivers_load(NULL);
294 if (descriptor_node_ptr == NULL)
296 jack_error(
"could not find any drivers in driver directory!");
300 while (descriptor_node_ptr != NULL)
303 if (driver_ptr == NULL)
305 jack_error(
"memory allocation of jackctl_driver structure failed.");
310 driver_ptr->parameters = NULL;
311 driver_ptr->set_parameters = NULL;
312 driver_ptr->infos = NULL;
314 if (!jackctl_add_driver_parameters(driver_ptr))
316 assert(driver_ptr->parameters == NULL);
321 server_ptr->drivers = jack_slist_append(server_ptr->drivers, driver_ptr);
324 node_ptr = descriptor_node_ptr;
325 descriptor_node_ptr = descriptor_node_ptr->next;
334 jackctl_server_free_drivers(
340 while (server_ptr->drivers)
342 next_node_ptr = server_ptr->drivers->next;
345 jackctl_free_driver_parameters(driver_ptr);
346 free(driver_ptr->desc_ptr->
params);
347 free(driver_ptr->desc_ptr);
350 free(server_ptr->drivers);
351 server_ptr->drivers = next_node_ptr;
356 jackctl_internals_load(
361 JSList *descriptor_node_ptr;
363 descriptor_node_ptr = jack_internals_load(NULL);
364 if (descriptor_node_ptr == NULL)
366 jack_error(
"could not find any internals in driver directory!");
370 while (descriptor_node_ptr != NULL)
373 if (internal_ptr == NULL)
375 jack_error(
"memory allocation of jackctl_driver structure failed.");
380 internal_ptr->parameters = NULL;
381 internal_ptr->set_parameters = NULL;
382 internal_ptr->refnum = -1;
384 if (!jackctl_add_driver_parameters((
struct jackctl_driver *)internal_ptr))
386 assert(internal_ptr->parameters == NULL);
391 server_ptr->internals = jack_slist_append(server_ptr->internals, internal_ptr);
394 node_ptr = descriptor_node_ptr;
395 descriptor_node_ptr = descriptor_node_ptr->next;
404 jackctl_server_free_internals(
410 while (server_ptr->internals)
412 next_node_ptr = server_ptr->internals->next;
415 jackctl_free_driver_parameters((
struct jackctl_driver *)internal_ptr);
416 free(internal_ptr->desc_ptr->
params);
417 free(internal_ptr->desc_ptr);
420 free(server_ptr->internals);
421 server_ptr->internals = next_node_ptr;
427 jackctl_server_free_parameters(
432 while (server_ptr->parameters)
434 next_node_ptr = server_ptr->parameters->next;
435 free(server_ptr->parameters->data);
436 free(server_ptr->parameters);
437 server_ptr->parameters = next_node_ptr;
443 static HANDLE waitEvent;
445 static void do_nothing_handler(
int signum)
447 printf(
"jack main caught signal %d\n", signum);
448 (void) signal(SIGINT, SIG_DFL);
456 if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
457 jack_error(
"CreateEvent fails err = %ld", GetLastError());
461 (void) signal(SIGINT, do_nothing_handler);
462 (void) signal(SIGABRT, do_nothing_handler);
463 (void) signal(SIGTERM, do_nothing_handler);
465 return (sigset_t)waitEvent;
470 if (WaitForSingleObject(waitEvent, INFINITE) != WAIT_OBJECT_0) {
471 jack_error(
"WaitForSingleObject fails err = %ld", GetLastError());
479 do_nothing_handler(
int sig)
486 snprintf (buf,
sizeof(buf),
"received signal %d during shutdown (ignored)\n", sig);
489 SERVER_EXPORT sigset_t
495 struct sigaction action;
504 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
532 sigemptyset(&signals);
533 sigaddset(&signals, SIGHUP);
534 sigaddset(&signals, SIGINT);
535 sigaddset(&signals, SIGQUIT);
536 sigaddset(&signals, SIGPIPE);
537 sigaddset(&signals, SIGTERM);
538 sigaddset(&signals, SIGUSR1);
539 sigaddset(&signals, SIGUSR2);
545 pthread_sigmask(SIG_BLOCK, &signals, 0);
551 sigfillset(&allsignals);
552 action.sa_handler = do_nothing_handler;
553 action.sa_mask = allsignals;
554 action.sa_flags = SA_RESTART|SA_RESETHAND;
556 for (i = 1; i < NSIG; i++)
558 if (sigismember (&signals, i))
560 sigaction(i, &action, 0);
574 #if defined(sun) && !defined(__sun__) // SUN compiler only, to check
577 sigwait(&signals, &sig);
579 fprintf(stderr,
"jack main caught signal %d\n", sig);
597 if (sig != SIGSEGV) {
601 sigprocmask(SIG_UNBLOCK, &signals, 0);
608 get_realtime_priority_constraint()
613 if (!jack_get_thread_realtime_priority_range(&min, &max))
621 if (constraint_ptr == NULL)
623 jack_error(
"Cannot allocate memory for jack_driver_param_constraint_desc_t structure.");
626 constraint_ptr->
flags = JACK_CONSTRAINT_FLAG_RANGE;
628 constraint_ptr->constraint.
range.min.i = min;
629 constraint_ptr->constraint.
range.max.i = max;
631 return constraint_ptr;
635 bool (* on_device_acquire)(
const char * device_name),
636 void (* on_device_release)(
const char * device_name))
642 if (server_ptr == NULL)
644 jack_error(
"Cannot allocate memory for jackctl_server structure.");
648 server_ptr->drivers = NULL;
649 server_ptr->internals = NULL;
650 server_ptr->parameters = NULL;
651 server_ptr->engine = NULL;
653 strcpy(value.
str, JACK_DEFAULT_SERVER_NAME);
654 if (jackctl_add_parameter(
655 &server_ptr->parameters,
657 "Server name to use.",
661 &server_ptr->default_name,
664 goto fail_free_parameters;
668 if (jackctl_add_parameter(
669 &server_ptr->parameters,
671 "Whether to use realtime mode.",
672 "Use realtime scheduling. This is needed for reliable low-latency performance. On most systems, it requires JACK to run with special scheduler and memory allocation privileges, which may be obtained in several ways. On Linux you should use PAM.",
674 &server_ptr->realtime,
675 &server_ptr->default_realtime,
678 goto fail_free_parameters;
682 if (jackctl_add_parameter(
683 &server_ptr->parameters,
685 "Scheduler priority when running in realtime mode.",
688 &server_ptr->realtime_priority,
689 &server_ptr->default_realtime_priority,
691 get_realtime_priority_constraint()) == NULL)
693 goto fail_free_parameters;
697 if (jackctl_add_parameter(
698 &server_ptr->parameters,
700 "Exit once all clients have closed their connections.",
703 &server_ptr->temporary,
704 &server_ptr->default_temporary,
707 goto fail_free_parameters;
711 if (jackctl_add_parameter(
712 &server_ptr->parameters,
717 &server_ptr->verbose,
718 &server_ptr->default_verbose,
721 goto fail_free_parameters;
725 if (jackctl_add_parameter(
726 &server_ptr->parameters,
728 "Client timeout limit in milliseconds.",
731 &server_ptr->client_timeout,
732 &server_ptr->default_client_timeout,
735 goto fail_free_parameters;
739 if (jackctl_add_parameter(
740 &server_ptr->parameters,
742 "Clocksource type : c(ycle) | h(pet) | s(ystem).",
745 &server_ptr->clock_source,
746 &server_ptr->default_clock_source,
749 goto fail_free_parameters;
753 if (jackctl_add_parameter(
754 &server_ptr->parameters,
756 "Maximum number of ports.",
759 &server_ptr->port_max,
760 &server_ptr->default_port_max,
763 goto fail_free_parameters;
767 if (jackctl_add_parameter(
768 &server_ptr->parameters,
770 "Replace shared memory registry.",
773 &server_ptr->replace_registry,
774 &server_ptr->default_replace_registry,
777 goto fail_free_parameters;
781 if (jackctl_add_parameter(
782 &server_ptr->parameters,
784 "Use server synchronous mode.",
788 &server_ptr->default_sync,
791 goto fail_free_parameters;
794 JackServerGlobals::on_device_acquire = on_device_acquire;
795 JackServerGlobals::on_device_release = on_device_release;
797 if (!jackctl_drivers_load(server_ptr))
799 goto fail_free_parameters;
803 jackctl_internals_load(server_ptr);
807 fail_free_parameters:
808 jackctl_server_free_parameters(server_ptr);
819 jackctl_server_free_drivers(server_ptr);
820 jackctl_server_free_internals(server_ptr);
821 jackctl_server_free_parameters(server_ptr);
828 return (server_ptr) ? server_ptr->drivers : NULL;
834 server_ptr->engine->Stop();
844 server_ptr->engine->Close();
845 delete server_ptr->engine;
848 jack_log(
"cleaning up shared memory");
854 JackTools::CleanupFiles(server_ptr->name.
str);
856 jack_log(
"unregistering server `%s'", server_ptr->name.
str);
858 jack_unregister_server(server_ptr->name.
str);
860 server_ptr->engine = NULL;
870 return (server_ptr) ? server_ptr->parameters : NULL;
880 if (!server_ptr || !driver_ptr) {
884 int rc = jack_register_server(server_ptr->name.
str, server_ptr->replace_registry.
b);
888 jack_error(
"`%s' server already active", server_ptr->name.
str);
891 jack_error(
"too many servers already active");
898 jack_log(
"server `%s' registered", server_ptr->name.
str);
903 JackTools::CleanupFiles(server_ptr->name.
str);
905 if (!server_ptr->realtime.
b && server_ptr->client_timeout.
i == 0) {
906 server_ptr->client_timeout.
i = 500;
910 if (server_ptr->port_max.
ui > PORT_NUM_MAX) {
911 jack_error(
"JACK server started with too much ports %d (when port max can be %d)", server_ptr->port_max.
ui, PORT_NUM_MAX);
918 server_ptr->temporary.
b,
919 server_ptr->client_timeout.
i,
920 server_ptr->realtime.
b,
921 server_ptr->realtime_priority.
i,
922 server_ptr->port_max.
ui,
923 server_ptr->verbose.
b,
924 (jack_timer_type_t)server_ptr->clock_source.
ui,
925 server_ptr->name.
str);
926 if (server_ptr->engine == NULL)
928 jack_error(
"Failed to create new JackServer object");
929 goto fail_unregister;
932 rc = server_ptr->engine->Open(driver_ptr->desc_ptr, driver_ptr->set_parameters);
935 jack_error(
"JackServer::Open() failed with %d", rc);
941 }
catch (std::exception e) {
946 delete server_ptr->engine;
947 server_ptr->engine = NULL;
950 jack_log(
"cleaning up shared memory");
956 JackTools::CleanupFiles(server_ptr->name.
str);
958 jack_log(
"unregistering server `%s'", server_ptr->name.
str);
960 jack_unregister_server(server_ptr->name.
str);
973 int rc = server_ptr->engine->Start();
974 bool result = rc >= 0;
977 jack_error(
"JackServer::Start() failed with %d", rc);
985 return (driver_ptr) ? driver_ptr->desc_ptr->
name : NULL;
995 return (driver_ptr) ? driver_ptr->parameters : NULL;
1000 return (driver_ptr) ? driver_ptr->desc_ptr : NULL;
1005 return (parameter_ptr) ? parameter_ptr->name : NULL;
1010 return (parameter_ptr) ? parameter_ptr->short_description : NULL;
1015 return (parameter_ptr) ? parameter_ptr->long_description : NULL;
1020 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->
flags & JACK_CONSTRAINT_FLAG_RANGE) != 0) :
false;
1025 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->
flags & JACK_CONSTRAINT_FLAG_RANGE) == 0):
false;
1030 if (!parameter_ptr) {
1039 return parameter_ptr->constraint_ptr->constraint.
enumeration.count;
1047 if (!parameter_ptr) {
1048 memset(&jackctl_value, 0,
sizeof(jackctl_value));
1049 return jackctl_value;
1052 value_ptr = ¶meter_ptr->constraint_ptr->constraint.
enumeration.possible_values_array[index].value;
1054 switch (parameter_ptr->type)
1057 jackctl_value.
i = value_ptr->i;
1060 jackctl_value.
ui = value_ptr->ui;
1063 jackctl_value.
c = value_ptr->c;
1066 strcpy(jackctl_value.
str, value_ptr->str);
1069 jack_error(
"bad driver parameter type %i (enum constraint)", (
int)parameter_ptr->type);
1073 return jackctl_value;
1078 return (parameter_ptr) ? parameter_ptr->constraint_ptr->constraint.
enumeration.possible_values_array[index].short_desc : NULL;
1083 if (!parameter_ptr || !min_ptr || !max_ptr) {
1087 switch (parameter_ptr->type)
1090 min_ptr->
i = parameter_ptr->constraint_ptr->constraint.
range.min.i;
1091 max_ptr->
i = parameter_ptr->constraint_ptr->constraint.
range.max.i;
1094 min_ptr->
ui = parameter_ptr->constraint_ptr->constraint.
range.min.ui;
1095 max_ptr->
ui = parameter_ptr->constraint_ptr->constraint.
range.max.ui;
1098 jack_error(
"bad driver parameter type %i (range constraint)", (
int)parameter_ptr->type);
1105 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->
flags & JACK_CONSTRAINT_FLAG_STRICT) != 0) :
false;
1110 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->
flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0) :
false;
1120 return (parameter_ptr) ? parameter_ptr->id : 0;
1125 return (parameter_ptr) ? parameter_ptr->is_set :
false;
1130 if (parameter_ptr) {
1131 return *parameter_ptr->value_ptr;
1134 memset(&jackctl_value, 0,
sizeof(jackctl_value));
1135 return jackctl_value;
1141 if (!parameter_ptr) {
1145 if (!parameter_ptr->is_set)
1150 parameter_ptr->is_set =
false;
1152 *parameter_ptr->value_ptr = *parameter_ptr->default_value_ptr;
1159 if (!parameter_ptr || !value_ptr) {
1163 bool new_driver_parameter;
1166 if (parameter_ptr->driver_ptr != NULL)
1169 new_driver_parameter = parameter_ptr->driver_parameter_ptr == NULL;
1170 if (new_driver_parameter)
1174 if (parameter_ptr->driver_parameter_ptr == NULL)
1176 jack_error (
"Allocation of jack_driver_param_t structure failed");
1180 parameter_ptr->driver_parameter_ptr->character = parameter_ptr->id;
1181 parameter_ptr->driver_ptr->set_parameters = jack_slist_append(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr);
1184 switch (parameter_ptr->type)
1187 parameter_ptr->driver_parameter_ptr->value.i = value_ptr->
i;
1190 parameter_ptr->driver_parameter_ptr->value.ui = value_ptr->
ui;
1193 parameter_ptr->driver_parameter_ptr->value.c = value_ptr->
c;
1196 strcpy(parameter_ptr->driver_parameter_ptr->value.str, value_ptr->
str);
1199 parameter_ptr->driver_parameter_ptr->value.i = value_ptr->
b;
1202 jack_error(
"unknown parameter type %i", (
int)parameter_ptr->type);
1205 if (new_driver_parameter)
1207 parameter_ptr->driver_ptr->set_parameters = jack_slist_remove(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr);
1214 parameter_ptr->is_set =
true;
1215 *parameter_ptr->value_ptr = *value_ptr;
1222 if (parameter_ptr) {
1223 return *parameter_ptr->default_value_ptr;
1226 memset(&jackctl_value, 0,
sizeof(jackctl_value));
1227 return jackctl_value;
1235 return (server_ptr) ? server_ptr->internals : NULL;
1240 return (internal_ptr) ? internal_ptr->desc_ptr->
name : NULL;
1245 return (internal_ptr) ? internal_ptr->parameters : NULL;
1252 if (!server_ptr || !
internal) {
1257 if (server_ptr->engine != NULL) {
1258 server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status);
1259 return (internal->refnum > 0);
1269 if (!server_ptr || !
internal) {
1274 if (server_ptr->engine != NULL && internal->refnum > 0) {
1276 return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0);
1284 if (server_ptr && server_ptr->engine) {
1285 if (server_ptr->engine->IsRunning()) {
1286 jack_error(
"cannot add a slave in a running server");
1289 JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters);
1291 driver_ptr->infos = jack_slist_append(driver_ptr->infos, info);
1304 if (server_ptr && server_ptr->engine) {
1305 if (server_ptr->engine->IsRunning()) {
1306 jack_error(
"cannot remove a slave from a running server");
1309 if (driver_ptr->infos) {
1312 driver_ptr->infos = jack_slist_remove(driver_ptr->infos, info);
1313 server_ptr->engine->RemoveSlave(info);
1327 if (server_ptr && server_ptr->engine) {
1328 return (server_ptr->engine->
SwitchMaster(driver_ptr->desc_ptr, driver_ptr->set_parameters) == 0);