jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1533 lines
41KB

  1. // u/* -*- Mode: C++ ; c-basic-offset: 4 -*- */
  2. /*
  3. JACK control API implementation
  4. Copyright (C) 2008 Nedko Arnaudov
  5. Copyright (C) 2008 Grame
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; version 2 of the License.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifndef WIN32
  18. #include <stdint.h>
  19. #include <dirent.h>
  20. #include <pthread.h>
  21. #endif
  22. #include "config.h"
  23. #include "jack/internal.h"
  24. #include <string.h>
  25. #include <errno.h>
  26. #include <stdio.h>
  27. #include <assert.h>
  28. #include <signal.h>
  29. #include "jack/jslist.h"
  30. #include "jack/driver_interface.h"
  31. #include "jack/driver.h"
  32. #include "jack/engine.h"
  33. //#include "JackError.h"
  34. //#include "JackServer.h"
  35. //#include "shm.h"
  36. //#include "JackTools.h"
  37. //#include "JackControlAPI.h"
  38. //#include "JackLockedEngine.h"
  39. //#include "JackConstants.h"
  40. //#include "JackDriverLoader.h"
  41. //#include "JackServerGlobals.h"
  42. #include "jack/control.h"
  43. /*
  44. * XXX: dont like statics here.
  45. */
  46. static JSList *drivers = NULL;
  47. struct jackctl_server
  48. {
  49. JSList * drivers;
  50. JSList * internals;
  51. JSList * parameters;
  52. jack_engine_t * engine;
  53. /* string, server name */
  54. union jackctl_parameter_value name;
  55. union jackctl_parameter_value default_name;
  56. /* bool, whether to be "realtime" */
  57. union jackctl_parameter_value realtime;
  58. union jackctl_parameter_value default_realtime;
  59. /* int32_t */
  60. union jackctl_parameter_value realtime_priority;
  61. union jackctl_parameter_value default_realtime_priority;
  62. /* bool, whether to exit once all clients have closed their connections */
  63. union jackctl_parameter_value temporary;
  64. union jackctl_parameter_value default_temporary;
  65. /* bool, whether to be verbose */
  66. union jackctl_parameter_value verbose;
  67. union jackctl_parameter_value default_verbose;
  68. /* int32_t, msecs; if zero, use period size. */
  69. union jackctl_parameter_value client_timeout;
  70. union jackctl_parameter_value default_client_timeout;
  71. /* uint32_t, clock source type */
  72. union jackctl_parameter_value clock_source;
  73. union jackctl_parameter_value default_clock_source;
  74. /* uint32_t, max port number */
  75. union jackctl_parameter_value port_max;
  76. union jackctl_parameter_value default_port_max;
  77. /* bool */
  78. union jackctl_parameter_value replace_registry;
  79. union jackctl_parameter_value default_replace_registry;
  80. /* bool, use mlock */
  81. union jackctl_parameter_value do_mlock;
  82. union jackctl_parameter_value default_do_mlock;
  83. /* bool, munlock gui libraries */
  84. union jackctl_parameter_value do_unlock;
  85. union jackctl_parameter_value default_do_unlock;
  86. /* bool, dont zombify... */
  87. union jackctl_parameter_value nozombies;
  88. union jackctl_parameter_value default_nozombies;
  89. };
  90. struct jackctl_driver
  91. {
  92. jack_driver_desc_t * desc_ptr;
  93. JSList * parameters;
  94. JSList * set_parameters;
  95. };
  96. struct jackctl_internal
  97. {
  98. jack_driver_desc_t * desc_ptr;
  99. JSList * parameters;
  100. JSList * set_parameters;
  101. int refnum;
  102. };
  103. struct jackctl_parameter
  104. {
  105. const char * name;
  106. const char * short_description;
  107. const char * long_description;
  108. jackctl_param_type_t type;
  109. bool is_set;
  110. union jackctl_parameter_value * value_ptr;
  111. union jackctl_parameter_value * default_value_ptr;
  112. union jackctl_parameter_value value;
  113. union jackctl_parameter_value default_value;
  114. struct jackctl_driver * driver_ptr;
  115. char id;
  116. jack_driver_param_t * driver_parameter_ptr;
  117. jack_driver_param_constraint_desc_t * constraint_ptr;
  118. };
  119. static
  120. struct jackctl_parameter *
  121. jackctl_add_parameter(
  122. JSList ** parameters_list_ptr_ptr,
  123. const char * name,
  124. const char * short_description,
  125. const char * long_description,
  126. jackctl_param_type_t type,
  127. union jackctl_parameter_value * value_ptr,
  128. union jackctl_parameter_value * default_value_ptr,
  129. union jackctl_parameter_value value,
  130. jack_driver_param_constraint_desc_t * constraint_ptr)
  131. {
  132. struct jackctl_parameter * parameter_ptr;
  133. parameter_ptr = (struct jackctl_parameter *)malloc(sizeof(struct jackctl_parameter));
  134. if (parameter_ptr == NULL)
  135. {
  136. jack_error("Cannot allocate memory for jackctl_parameter structure.");
  137. goto fail;
  138. }
  139. parameter_ptr->name = name;
  140. parameter_ptr->short_description = short_description;
  141. parameter_ptr->long_description = long_description;
  142. parameter_ptr->type = type;
  143. parameter_ptr->is_set = false;
  144. if (value_ptr == NULL)
  145. {
  146. value_ptr = &parameter_ptr->value;
  147. }
  148. if (default_value_ptr == NULL)
  149. {
  150. default_value_ptr = &parameter_ptr->default_value;
  151. }
  152. parameter_ptr->value_ptr = value_ptr;
  153. parameter_ptr->default_value_ptr = default_value_ptr;
  154. *value_ptr = *default_value_ptr = value;
  155. parameter_ptr->driver_ptr = NULL;
  156. parameter_ptr->driver_parameter_ptr = NULL;
  157. parameter_ptr->id = 0;
  158. parameter_ptr->constraint_ptr = constraint_ptr;
  159. *parameters_list_ptr_ptr = jack_slist_append(*parameters_list_ptr_ptr, parameter_ptr);
  160. return parameter_ptr;
  161. fail:
  162. return NULL;
  163. }
  164. static
  165. void
  166. jackctl_free_driver_parameters(
  167. struct jackctl_driver * driver_ptr)
  168. {
  169. JSList * next_node_ptr;
  170. while (driver_ptr->parameters)
  171. {
  172. next_node_ptr = driver_ptr->parameters->next;
  173. free(driver_ptr->parameters->data);
  174. free(driver_ptr->parameters);
  175. driver_ptr->parameters = next_node_ptr;
  176. }
  177. while (driver_ptr->set_parameters)
  178. {
  179. next_node_ptr = driver_ptr->set_parameters->next;
  180. free(driver_ptr->set_parameters->data);
  181. free(driver_ptr->set_parameters);
  182. driver_ptr->set_parameters = next_node_ptr;
  183. }
  184. }
  185. static
  186. bool
  187. jackctl_add_driver_parameters(
  188. struct jackctl_driver * driver_ptr)
  189. {
  190. uint32_t i;
  191. union jackctl_parameter_value jackctl_value;
  192. jackctl_param_type_t jackctl_type;
  193. struct jackctl_parameter * parameter_ptr;
  194. jack_driver_param_desc_t * descriptor_ptr;
  195. for (i = 0 ; i < driver_ptr->desc_ptr->nparams ; i++)
  196. {
  197. descriptor_ptr = driver_ptr->desc_ptr->params + i;
  198. switch (descriptor_ptr->type)
  199. {
  200. case JackDriverParamInt:
  201. jackctl_type = JackParamInt;
  202. jackctl_value.i = descriptor_ptr->value.i;
  203. break;
  204. case JackDriverParamUInt:
  205. jackctl_type = JackParamUInt;
  206. jackctl_value.ui = descriptor_ptr->value.ui;
  207. break;
  208. case JackDriverParamChar:
  209. jackctl_type = JackParamChar;
  210. jackctl_value.c = descriptor_ptr->value.c;
  211. break;
  212. case JackDriverParamString:
  213. jackctl_type = JackParamString;
  214. strcpy(jackctl_value.str, descriptor_ptr->value.str);
  215. break;
  216. case JackDriverParamBool:
  217. jackctl_type = JackParamBool;
  218. jackctl_value.b = descriptor_ptr->value.i;
  219. break;
  220. default:
  221. jack_error("unknown driver parameter type %i", (int)descriptor_ptr->type);
  222. assert(0);
  223. goto fail;
  224. }
  225. parameter_ptr = jackctl_add_parameter(
  226. &driver_ptr->parameters,
  227. descriptor_ptr->name,
  228. descriptor_ptr->short_desc,
  229. descriptor_ptr->long_desc,
  230. jackctl_type,
  231. NULL,
  232. NULL,
  233. jackctl_value,
  234. descriptor_ptr->constraint);
  235. if (parameter_ptr == NULL)
  236. {
  237. goto fail;
  238. }
  239. parameter_ptr->driver_ptr = driver_ptr;
  240. parameter_ptr->id = descriptor_ptr->character;
  241. }
  242. return true;
  243. fail:
  244. jackctl_free_driver_parameters(driver_ptr);
  245. return false;
  246. }
  247. static jack_driver_desc_t *
  248. jack_drivers_get_descriptor (JSList * drivers, const char * sofile)
  249. {
  250. jack_driver_desc_t * descriptor, * other_descriptor;
  251. JackDriverDescFunction so_get_descriptor;
  252. JSList * node;
  253. void * dlhandle;
  254. char * filename;
  255. const char * dlerr;
  256. int err;
  257. char* driver_dir;
  258. if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
  259. driver_dir = ADDON_DIR;
  260. }
  261. filename = malloc (strlen (driver_dir) + 1 + strlen (sofile) + 1);
  262. sprintf (filename, "%s/%s", driver_dir, sofile);
  263. // if (verbose) {
  264. // jack_info ("getting driver descriptor from %s", filename);
  265. // }
  266. if ((dlhandle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL)) == NULL) {
  267. jack_error ("could not open driver .so '%s': %s\n", filename, dlerror ());
  268. free (filename);
  269. return NULL;
  270. }
  271. so_get_descriptor = (JackDriverDescFunction)
  272. dlsym (dlhandle, "driver_get_descriptor");
  273. if ((dlerr = dlerror ()) != NULL) {
  274. jack_error("%s", dlerr);
  275. dlclose (dlhandle);
  276. free (filename);
  277. return NULL;
  278. }
  279. if ((descriptor = so_get_descriptor ()) == NULL) {
  280. jack_error ("driver from '%s' returned NULL descriptor\n", filename);
  281. dlclose (dlhandle);
  282. free (filename);
  283. return NULL;
  284. }
  285. if ((err = dlclose (dlhandle)) != 0) {
  286. jack_error ("error closing driver .so '%s': %s\n", filename, dlerror ());
  287. }
  288. /* check it doesn't exist already */
  289. for (node = drivers; node; node = jack_slist_next (node)) {
  290. other_descriptor = (jack_driver_desc_t *) node->data;
  291. if (strcmp (descriptor->name, other_descriptor->name) == 0) {
  292. jack_error ("the drivers in '%s' and '%s' both have the name '%s'; using the first\n",
  293. other_descriptor->file, filename, other_descriptor->name);
  294. /* FIXME: delete the descriptor */
  295. free (filename);
  296. return NULL;
  297. }
  298. }
  299. snprintf (descriptor->file, sizeof(descriptor->file), "%s", filename);
  300. free (filename);
  301. return descriptor;
  302. }
  303. static JSList *
  304. jack_drivers_load ()
  305. {
  306. struct dirent * dir_entry;
  307. DIR * dir_stream;
  308. const char * ptr;
  309. int err;
  310. JSList * driver_list = NULL;
  311. jack_driver_desc_t * desc;
  312. char* driver_dir;
  313. if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
  314. driver_dir = ADDON_DIR;
  315. }
  316. /* search through the driver_dir and add get descriptors
  317. from the .so files in it */
  318. dir_stream = opendir (driver_dir);
  319. if (!dir_stream) {
  320. jack_error ("could not open driver directory %s: %s\n",
  321. driver_dir, strerror (errno));
  322. return NULL;
  323. }
  324. while ( (dir_entry = readdir (dir_stream)) ) {
  325. /* check the filename is of the right format */
  326. if (strncmp ("jack_", dir_entry->d_name, 5) != 0) {
  327. continue;
  328. }
  329. ptr = strrchr (dir_entry->d_name, '.');
  330. if (!ptr) {
  331. continue;
  332. }
  333. ptr++;
  334. if (strncmp ("so", ptr, 2) != 0) {
  335. continue;
  336. }
  337. desc = jack_drivers_get_descriptor (drivers, dir_entry->d_name);
  338. if (desc) {
  339. driver_list = jack_slist_append (driver_list, desc);
  340. }
  341. }
  342. err = closedir (dir_stream);
  343. if (err) {
  344. jack_error ("error closing driver directory %s: %s\n",
  345. driver_dir, strerror (errno));
  346. }
  347. if (!driver_list) {
  348. jack_error ("could not find any drivers in %s!\n", driver_dir);
  349. return NULL;
  350. }
  351. return driver_list;
  352. }
  353. static void
  354. jack_cleanup_files (const char *server_name)
  355. {
  356. DIR *dir;
  357. struct dirent *dirent;
  358. char dir_name[PATH_MAX+1] = "";
  359. jack_server_dir (server_name, dir_name);
  360. /* On termination, we remove all files that jackd creates so
  361. * subsequent attempts to start jackd will not believe that an
  362. * instance is already running. If the server crashes or is
  363. * terminated with SIGKILL, this is not possible. So, cleanup
  364. * is also attempted when jackd starts.
  365. *
  366. * There are several tricky issues. First, the previous JACK
  367. * server may have run for a different user ID, so its files
  368. * may be inaccessible. This is handled by using a separate
  369. * JACK_TMP_DIR subdirectory for each user. Second, there may
  370. * be other servers running with different names. Each gets
  371. * its own subdirectory within the per-user directory. The
  372. * current process has already registered as `server_name', so
  373. * we know there is no other server actively using that name.
  374. */
  375. /* nothing to do if the server directory does not exist */
  376. if ((dir = opendir (dir_name)) == NULL) {
  377. return;
  378. }
  379. /* unlink all the files in this directory, they are mine */
  380. while ((dirent = readdir (dir)) != NULL) {
  381. char fullpath[PATH_MAX+1];
  382. if ((strcmp (dirent->d_name, ".") == 0)
  383. || (strcmp (dirent->d_name, "..") == 0)) {
  384. continue;
  385. }
  386. snprintf (fullpath, sizeof (fullpath), "%s/%s",
  387. dir_name, dirent->d_name);
  388. if (unlink (fullpath)) {
  389. jack_error ("cannot unlink `%s' (%s)", fullpath,
  390. strerror (errno));
  391. }
  392. }
  393. closedir (dir);
  394. /* now, delete the per-server subdirectory, itself */
  395. if (rmdir (dir_name)) {
  396. jack_error ("cannot remove `%s' (%s)", dir_name,
  397. strerror (errno));
  398. }
  399. /* finally, delete the per-user subdirectory, if empty */
  400. if (rmdir (jack_user_dir ())) {
  401. if (errno != ENOTEMPTY) {
  402. jack_error ("cannot remove `%s' (%s)",
  403. jack_user_dir (), strerror (errno));
  404. }
  405. }
  406. }
  407. static int
  408. jackctl_drivers_load(
  409. struct jackctl_server * server_ptr)
  410. {
  411. struct jackctl_driver * driver_ptr;
  412. JSList *node_ptr;
  413. JSList *descriptor_node_ptr;
  414. descriptor_node_ptr = jack_drivers_load();
  415. if (descriptor_node_ptr == NULL)
  416. {
  417. jack_error("could not find any drivers in driver directory!");
  418. return false;
  419. }
  420. while (descriptor_node_ptr != NULL)
  421. {
  422. driver_ptr = (struct jackctl_driver *)malloc(sizeof(struct jackctl_driver));
  423. if (driver_ptr == NULL)
  424. {
  425. jack_error("memory allocation of jackctl_driver structure failed.");
  426. goto next;
  427. }
  428. driver_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data;
  429. driver_ptr->parameters = NULL;
  430. driver_ptr->set_parameters = NULL;
  431. if (!jackctl_add_driver_parameters(driver_ptr))
  432. {
  433. assert(driver_ptr->parameters == NULL);
  434. free(driver_ptr);
  435. goto next;
  436. }
  437. server_ptr->drivers = jack_slist_append(server_ptr->drivers, driver_ptr);
  438. next:
  439. node_ptr = descriptor_node_ptr;
  440. descriptor_node_ptr = descriptor_node_ptr->next;
  441. free(node_ptr);
  442. }
  443. return true;
  444. }
  445. static
  446. void
  447. jackctl_server_free_drivers(
  448. struct jackctl_server * server_ptr)
  449. {
  450. JSList * next_node_ptr;
  451. struct jackctl_driver * driver_ptr;
  452. while (server_ptr->drivers)
  453. {
  454. next_node_ptr = server_ptr->drivers->next;
  455. driver_ptr = (struct jackctl_driver *)server_ptr->drivers->data;
  456. jackctl_free_driver_parameters(driver_ptr);
  457. free(driver_ptr->desc_ptr->params);
  458. free(driver_ptr->desc_ptr);
  459. free(driver_ptr);
  460. free(server_ptr->drivers);
  461. server_ptr->drivers = next_node_ptr;
  462. }
  463. }
  464. static int
  465. jackctl_internals_load(
  466. struct jackctl_server * server_ptr)
  467. {
  468. struct jackctl_internal * internal_ptr;
  469. JSList *node_ptr;
  470. JSList *descriptor_node_ptr = NULL;
  471. //descriptor_node_ptr = jack_internals_load(NULL);
  472. if (descriptor_node_ptr == NULL)
  473. {
  474. return false;
  475. }
  476. while (descriptor_node_ptr != NULL)
  477. {
  478. internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal));
  479. if (internal_ptr == NULL)
  480. {
  481. jack_error("memory allocation of jackctl_driver structure failed.");
  482. goto next;
  483. }
  484. internal_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data;
  485. internal_ptr->parameters = NULL;
  486. internal_ptr->set_parameters = NULL;
  487. if (!jackctl_add_driver_parameters((struct jackctl_driver *)internal_ptr))
  488. {
  489. assert(internal_ptr->parameters == NULL);
  490. free(internal_ptr);
  491. goto next;
  492. }
  493. server_ptr->internals = jack_slist_append(server_ptr->internals, internal_ptr);
  494. next:
  495. node_ptr = descriptor_node_ptr;
  496. descriptor_node_ptr = descriptor_node_ptr->next;
  497. free(node_ptr);
  498. }
  499. return true;
  500. }
  501. static
  502. void
  503. jackctl_server_free_internals(
  504. struct jackctl_server * server_ptr)
  505. {
  506. JSList * next_node_ptr;
  507. struct jackctl_internal * internal_ptr;
  508. while (server_ptr->internals)
  509. {
  510. next_node_ptr = server_ptr->internals->next;
  511. internal_ptr = (struct jackctl_internal *)server_ptr->internals->data;
  512. jackctl_free_driver_parameters((struct jackctl_driver *)internal_ptr);
  513. free(internal_ptr->desc_ptr->params);
  514. free(internal_ptr->desc_ptr);
  515. free(internal_ptr);
  516. free(server_ptr->internals);
  517. server_ptr->internals = next_node_ptr;
  518. }
  519. }
  520. static
  521. void
  522. jackctl_server_free_parameters(
  523. struct jackctl_server * server_ptr)
  524. {
  525. JSList * next_node_ptr;
  526. while (server_ptr->parameters)
  527. {
  528. next_node_ptr = server_ptr->parameters->next;
  529. free(server_ptr->parameters->data);
  530. free(server_ptr->parameters);
  531. server_ptr->parameters = next_node_ptr;
  532. }
  533. }
  534. #ifdef WIN32
  535. static HANDLE waitEvent;
  536. static void do_nothing_handler(int signum)
  537. {
  538. printf("jack main caught signal %d\n", signum);
  539. (void) signal(SIGINT, SIG_DFL);
  540. SetEvent(waitEvent);
  541. }
  542. sigset_t
  543. jackctl_setup_signals(
  544. unsigned int flags)
  545. {
  546. if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
  547. jack_error("CreateEvent fails err = %ld", GetLastError());
  548. return 0;
  549. }
  550. (void) signal(SIGINT, do_nothing_handler);
  551. (void) signal(SIGABRT, do_nothing_handler);
  552. (void) signal(SIGTERM, do_nothing_handler);
  553. return (sigset_t)waitEvent;
  554. }
  555. void jackctl_wait_signals(sigset_t signals)
  556. {
  557. if (WaitForSingleObject(waitEvent, INFINITE) != WAIT_OBJECT_0) {
  558. jack_error("WaitForSingleObject fails err = %ld", GetLastError());
  559. }
  560. }
  561. #else
  562. static
  563. void
  564. do_nothing_handler(int sig)
  565. {
  566. /* this is used by the child (active) process, but it never
  567. gets called unless we are already shutting down after
  568. another signal.
  569. */
  570. char buf[64];
  571. snprintf (buf, sizeof(buf), "received signal %d during shutdown (ignored)\n", sig);
  572. }
  573. sigset_t
  574. jackctl_setup_signals(
  575. unsigned int flags)
  576. {
  577. sigset_t signals;
  578. sigset_t allsignals;
  579. struct sigaction action;
  580. int i;
  581. /* ensure that we are in our own process group so that
  582. kill (SIG, -pgrp) does the right thing.
  583. */
  584. setsid();
  585. pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  586. /* what's this for?
  587. POSIX says that signals are delivered like this:
  588. * if a thread has blocked that signal, it is not
  589. a candidate to receive the signal.
  590. * of all threads not blocking the signal, pick
  591. one at random, and deliver the signal.
  592. this means that a simple-minded multi-threaded program can
  593. expect to get POSIX signals delivered randomly to any one
  594. of its threads,
  595. here, we block all signals that we think we might receive
  596. and want to catch. all "child" threads will inherit this
  597. setting. if we create a thread that calls sigwait() on the
  598. same set of signals, implicitly unblocking all those
  599. signals. any of those signals that are delivered to the
  600. process will be delivered to that thread, and that thread
  601. alone. this makes cleanup for a signal-driven exit much
  602. easier, since we know which thread is doing it and more
  603. importantly, we are free to call async-unsafe functions,
  604. because the code is executing in normal thread context
  605. after a return from sigwait().
  606. */
  607. sigemptyset(&signals);
  608. sigaddset(&signals, SIGHUP);
  609. sigaddset(&signals, SIGINT);
  610. sigaddset(&signals, SIGQUIT);
  611. sigaddset(&signals, SIGPIPE);
  612. sigaddset(&signals, SIGTERM);
  613. sigaddset(&signals, SIGUSR1);
  614. sigaddset(&signals, SIGUSR2);
  615. /* all child threads will inherit this mask unless they
  616. * explicitly reset it
  617. */
  618. pthread_sigmask(SIG_BLOCK, &signals, 0);
  619. /* install a do-nothing handler because otherwise pthreads
  620. behaviour is undefined when we enter sigwait.
  621. */
  622. sigfillset(&allsignals);
  623. action.sa_handler = do_nothing_handler;
  624. action.sa_mask = allsignals;
  625. action.sa_flags = SA_RESTART|SA_RESETHAND;
  626. for (i = 1; i < NSIG; i++)
  627. {
  628. if (sigismember (&signals, i))
  629. {
  630. sigaction(i, &action, 0);
  631. }
  632. }
  633. return signals;
  634. }
  635. void
  636. jackctl_wait_signals(sigset_t signals)
  637. {
  638. int sig;
  639. bool waiting = true;
  640. while (waiting) {
  641. #if defined(sun) && !defined(__sun__) // SUN compiler only, to check
  642. sigwait(&signals);
  643. #else
  644. sigwait(&signals, &sig);
  645. #endif
  646. fprintf(stderr, "jack main caught signal %d\n", sig);
  647. switch (sig) {
  648. case SIGUSR1:
  649. //jack_dump_configuration(engine, 1);
  650. break;
  651. case SIGUSR2:
  652. // driver exit
  653. waiting = false;
  654. break;
  655. case SIGTTOU:
  656. break;
  657. default:
  658. waiting = false;
  659. break;
  660. }
  661. }
  662. if (sig != SIGSEGV) {
  663. // unblock signals so we can see them during shutdown.
  664. // this will help prod developers not to lose sight of
  665. // bugs that cause segfaults etc. during shutdown.
  666. sigprocmask(SIG_UNBLOCK, &signals, 0);
  667. }
  668. }
  669. #endif
  670. static sigset_t
  671. jackctl_block_signals()
  672. {
  673. sigset_t signals;
  674. sigset_t oldsignals;
  675. sigemptyset(&signals);
  676. sigaddset(&signals, SIGHUP);
  677. sigaddset(&signals, SIGINT);
  678. sigaddset(&signals, SIGQUIT);
  679. sigaddset(&signals, SIGPIPE);
  680. sigaddset(&signals, SIGTERM);
  681. sigaddset(&signals, SIGUSR1);
  682. sigaddset(&signals, SIGUSR2);
  683. pthread_sigmask(SIG_BLOCK, &signals, &oldsignals);
  684. return oldsignals;
  685. }
  686. static void
  687. jackctl_unblock_signals(sigset_t oldsignals)
  688. {
  689. pthread_sigmask(SIG_SETMASK, &oldsignals, 0);
  690. }
  691. static
  692. jack_driver_param_constraint_desc_t *
  693. get_realtime_priority_constraint()
  694. {
  695. #ifndef __OpenBSD__
  696. jack_driver_param_constraint_desc_t * constraint_ptr;
  697. int max = sched_get_priority_max (SCHED_FIFO);
  698. int min = sched_get_priority_min (SCHED_FIFO);
  699. //jack_info("realtime priority range is (%d,%d)", min, max);
  700. constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t));
  701. if (constraint_ptr == NULL)
  702. {
  703. jack_error("Cannot allocate memory for jack_driver_param_constraint_desc_t structure.");
  704. return NULL;
  705. }
  706. constraint_ptr->flags = JACK_CONSTRAINT_FLAG_RANGE;
  707. constraint_ptr->constraint.range.min.i = min;
  708. constraint_ptr->constraint.range.max.i = max;
  709. return constraint_ptr;
  710. #else
  711. return NULL
  712. #endif
  713. }
  714. jackctl_server_t * jackctl_server_create(
  715. bool (* on_device_acquire)(const char * device_name),
  716. void (* on_device_release)(const char * device_name))
  717. {
  718. struct jackctl_server * server_ptr;
  719. union jackctl_parameter_value value;
  720. server_ptr = (struct jackctl_server *)malloc(sizeof(struct jackctl_server));
  721. if (server_ptr == NULL)
  722. {
  723. jack_error("Cannot allocate memory for jackctl_server structure.");
  724. goto fail;
  725. }
  726. server_ptr->drivers = NULL;
  727. server_ptr->internals = NULL;
  728. server_ptr->parameters = NULL;
  729. server_ptr->engine = NULL;
  730. strcpy(value.str, jack_default_server_name() );
  731. if (jackctl_add_parameter(
  732. &server_ptr->parameters,
  733. "name",
  734. "Server name to use.",
  735. "",
  736. JackParamString,
  737. &server_ptr->name,
  738. &server_ptr->default_name,
  739. value, NULL) == NULL)
  740. {
  741. goto fail_free_parameters;
  742. }
  743. value.b = false;
  744. if (jackctl_add_parameter(
  745. &server_ptr->parameters,
  746. "realtime",
  747. "Whether to use realtime mode.",
  748. "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.",
  749. JackParamBool,
  750. &server_ptr->realtime,
  751. &server_ptr->default_realtime,
  752. value, NULL) == NULL)
  753. {
  754. goto fail_free_parameters;
  755. }
  756. value.i = 10;
  757. if (jackctl_add_parameter(
  758. &server_ptr->parameters,
  759. "realtime-priority",
  760. "Scheduler priority when running in realtime mode.",
  761. "",
  762. JackParamInt,
  763. &server_ptr->realtime_priority,
  764. &server_ptr->default_realtime_priority,
  765. value,
  766. get_realtime_priority_constraint()
  767. ) == NULL)
  768. {
  769. goto fail_free_parameters;
  770. }
  771. value.b = false;
  772. if (jackctl_add_parameter(
  773. &server_ptr->parameters,
  774. "temporary",
  775. "Exit once all clients have closed their connections.",
  776. "",
  777. JackParamBool,
  778. &server_ptr->temporary,
  779. &server_ptr->default_temporary,
  780. value, NULL) == NULL)
  781. {
  782. goto fail_free_parameters;
  783. }
  784. value.b = false;
  785. if (jackctl_add_parameter(
  786. &server_ptr->parameters,
  787. "verbose",
  788. "Verbose mode.",
  789. "",
  790. JackParamBool,
  791. &server_ptr->verbose,
  792. &server_ptr->default_verbose,
  793. value, NULL) == NULL)
  794. {
  795. goto fail_free_parameters;
  796. }
  797. value.i = 0;
  798. if (jackctl_add_parameter(
  799. &server_ptr->parameters,
  800. "client-timeout",
  801. "Client timeout limit in milliseconds.",
  802. "",
  803. JackParamInt,
  804. &server_ptr->client_timeout,
  805. &server_ptr->default_client_timeout,
  806. value, NULL) == NULL)
  807. {
  808. goto fail_free_parameters;
  809. }
  810. value.ui = 0;
  811. if (jackctl_add_parameter(
  812. &server_ptr->parameters,
  813. "clock-source",
  814. "Clocksource type : c(ycle) | h(pet) | s(ystem).",
  815. "",
  816. JackParamUInt,
  817. &server_ptr->clock_source,
  818. &server_ptr->default_clock_source,
  819. value, NULL) == NULL)
  820. {
  821. goto fail_free_parameters;
  822. }
  823. value.ui = 128;
  824. if (jackctl_add_parameter(
  825. &server_ptr->parameters,
  826. "port-max",
  827. "Maximum number of ports.",
  828. "",
  829. JackParamUInt,
  830. &server_ptr->port_max,
  831. &server_ptr->default_port_max,
  832. value, NULL) == NULL)
  833. {
  834. goto fail_free_parameters;
  835. }
  836. value.b = false;
  837. if (jackctl_add_parameter(
  838. &server_ptr->parameters,
  839. "replace-registry",
  840. "Replace shared memory registry.",
  841. "",
  842. JackParamBool,
  843. &server_ptr->replace_registry,
  844. &server_ptr->default_replace_registry,
  845. value, NULL) == NULL)
  846. {
  847. goto fail_free_parameters;
  848. }
  849. value.b = false;
  850. if (jackctl_add_parameter(
  851. &server_ptr->parameters,
  852. "mlock",
  853. "Use mlock.",
  854. "",
  855. JackParamBool,
  856. &server_ptr->do_mlock,
  857. &server_ptr->default_do_mlock,
  858. value, NULL) == NULL)
  859. {
  860. goto fail_free_parameters;
  861. }
  862. value.b = false;
  863. if (jackctl_add_parameter(
  864. &server_ptr->parameters,
  865. "unlock",
  866. "munlock memory for big libraries",
  867. "",
  868. JackParamBool,
  869. &server_ptr->do_unlock,
  870. &server_ptr->default_do_unlock,
  871. value, NULL) == NULL)
  872. {
  873. goto fail_free_parameters;
  874. }
  875. value.b = false;
  876. if (jackctl_add_parameter(
  877. &server_ptr->parameters,
  878. "nozombies",
  879. "dont zombifiy offending clients",
  880. "",
  881. JackParamBool,
  882. &server_ptr->nozombies,
  883. &server_ptr->default_nozombies,
  884. value, NULL) == NULL)
  885. {
  886. goto fail_free_parameters;
  887. }
  888. //TODO: need
  889. //JackServerGlobals::on_device_acquire = on_device_acquire;
  890. //JackServerGlobals::on_device_release = on_device_release;
  891. if (!jackctl_drivers_load(server_ptr))
  892. {
  893. goto fail_free_parameters;
  894. }
  895. /* Allowed to fail */
  896. jackctl_internals_load(server_ptr);
  897. return server_ptr;
  898. fail_free_parameters:
  899. jackctl_server_free_parameters(server_ptr);
  900. free(server_ptr);
  901. fail:
  902. return NULL;
  903. }
  904. void jackctl_server_destroy(jackctl_server_t *server_ptr)
  905. {
  906. jackctl_server_free_drivers(server_ptr);
  907. jackctl_server_free_internals(server_ptr);
  908. jackctl_server_free_parameters(server_ptr);
  909. free(server_ptr);
  910. }
  911. const JSList * jackctl_server_get_drivers_list(jackctl_server_t *server_ptr)
  912. {
  913. return server_ptr->drivers;
  914. }
  915. bool jackctl_server_stop(jackctl_server_t *server_ptr)
  916. {
  917. //jack_engine_driver_exit (server_ptr->engine);
  918. jack_engine_delete (server_ptr->engine);
  919. /* clean up shared memory and files from this server instance */
  920. //jack_log("cleaning up shared memory");
  921. jack_cleanup_shm();
  922. //jack_log("cleaning up files");
  923. jack_cleanup_files (server_ptr->name.str);
  924. //jack_log("unregistering server `%s'", server_ptr->name.str);
  925. jack_unregister_server(server_ptr->name.str);
  926. server_ptr->engine = NULL;
  927. return true;
  928. }
  929. const JSList * jackctl_server_get_parameters(jackctl_server_t *server_ptr)
  930. {
  931. return server_ptr->parameters;
  932. }
  933. bool
  934. jackctl_server_start(
  935. jackctl_server_t *server_ptr,
  936. jackctl_driver_t *driver_ptr)
  937. {
  938. int rc;
  939. sigset_t oldsignals;
  940. // TODO:
  941. int frame_time_offset = 0;
  942. rc = jack_register_server (server_ptr->name.str, server_ptr->replace_registry.b);
  943. switch (rc)
  944. {
  945. case EEXIST:
  946. jack_error("`%s' server already active", server_ptr->name.str);
  947. goto fail;
  948. case ENOSPC:
  949. jack_error("too many servers already active");
  950. goto fail;
  951. case ENOMEM:
  952. jack_error("no access to shm registry");
  953. goto fail;
  954. }
  955. //jack_log("server `%s' registered", server_ptr->name.str);
  956. /* clean up shared memory and files from any previous
  957. * instance of this server name */
  958. jack_cleanup_shm ();
  959. jack_cleanup_files (server_ptr->name.str);
  960. if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0)
  961. server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */
  962. oldsignals = jackctl_block_signals();
  963. if ((server_ptr->engine = jack_engine_new (server_ptr->realtime.b, server_ptr->realtime_priority.i,
  964. server_ptr->do_mlock.b, server_ptr->do_unlock.b, server_ptr->name.str,
  965. server_ptr->temporary.b, server_ptr->verbose.b, server_ptr->client_timeout.i,
  966. server_ptr->port_max.i, getpid(), frame_time_offset,
  967. server_ptr->nozombies.b, drivers)) == 0) {
  968. jack_error ("cannot create engine");
  969. goto fail_unregister;
  970. }
  971. if (jack_engine_load_driver (server_ptr->engine, driver_ptr->desc_ptr, driver_ptr->set_parameters))
  972. {
  973. jack_error ("cannot load driver module %s", driver_ptr->desc_ptr->name);
  974. goto fail_delete;
  975. }
  976. if (server_ptr->engine->driver->start (server_ptr->engine->driver) != 0) {
  977. jack_error ("cannot start driver");
  978. goto fail_close;
  979. }
  980. jackctl_unblock_signals( oldsignals );
  981. return true;
  982. fail_close:
  983. fail_delete:
  984. jack_engine_delete (server_ptr->engine);
  985. server_ptr->engine = NULL;
  986. fail_unregister:
  987. //jack_log("cleaning up shared memory");
  988. jack_cleanup_shm();
  989. //jack_log("cleaning up files");
  990. jack_cleanup_files(server_ptr->name.str);
  991. //jack_log("unregistering server `%s'", server_ptr->name.str);
  992. jack_unregister_server(server_ptr->name.str);
  993. jackctl_unblock_signals( oldsignals );
  994. fail:
  995. return false;
  996. }
  997. const char * jackctl_driver_get_name(jackctl_driver_t *driver_ptr)
  998. {
  999. return driver_ptr->desc_ptr->name;
  1000. }
  1001. const JSList * jackctl_driver_get_parameters(jackctl_driver_t *driver_ptr)
  1002. {
  1003. return driver_ptr->parameters;
  1004. }
  1005. jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver_t *driver_ptr)
  1006. {
  1007. return driver_ptr->desc_ptr;
  1008. }
  1009. const char * jackctl_parameter_get_name(jackctl_parameter_t *parameter_ptr)
  1010. {
  1011. return parameter_ptr->name;
  1012. }
  1013. const char * jackctl_parameter_get_short_description(jackctl_parameter_t *parameter_ptr)
  1014. {
  1015. return parameter_ptr->short_description;
  1016. }
  1017. const char * jackctl_parameter_get_long_description(jackctl_parameter_t *parameter_ptr)
  1018. {
  1019. return parameter_ptr->long_description;
  1020. }
  1021. bool jackctl_parameter_has_range_constraint(jackctl_parameter_t *parameter_ptr)
  1022. {
  1023. return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) != 0;
  1024. }
  1025. bool jackctl_parameter_has_enum_constraint(jackctl_parameter_t *parameter_ptr)
  1026. {
  1027. return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0;
  1028. }
  1029. uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter_t *parameter_ptr)
  1030. {
  1031. if (!jackctl_parameter_has_enum_constraint(parameter_ptr))
  1032. {
  1033. return 0;
  1034. }
  1035. return parameter_ptr->constraint_ptr->constraint.enumeration.count;
  1036. }
  1037. union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter_t *parameter_ptr, uint32_t index)
  1038. {
  1039. jack_driver_param_value_t * value_ptr;
  1040. union jackctl_parameter_value jackctl_value;
  1041. value_ptr = &parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].value;
  1042. switch (parameter_ptr->type)
  1043. {
  1044. case JackParamInt:
  1045. jackctl_value.i = value_ptr->i;
  1046. break;
  1047. case JackParamUInt:
  1048. jackctl_value.ui = value_ptr->ui;
  1049. break;
  1050. case JackParamChar:
  1051. jackctl_value.c = value_ptr->c;
  1052. break;
  1053. case JackParamString:
  1054. strcpy(jackctl_value.str, value_ptr->str);
  1055. break;
  1056. default:
  1057. jack_error("bad driver parameter type %i (enum constraint)", (int)parameter_ptr->type);
  1058. assert(0);
  1059. }
  1060. return jackctl_value;
  1061. }
  1062. const char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter_t *parameter_ptr, uint32_t index)
  1063. {
  1064. return parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].short_desc;
  1065. }
  1066. void jackctl_parameter_get_range_constraint(jackctl_parameter_t *parameter_ptr, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr)
  1067. {
  1068. switch (parameter_ptr->type)
  1069. {
  1070. case JackParamInt:
  1071. min_ptr->i = parameter_ptr->constraint_ptr->constraint.range.min.i;
  1072. max_ptr->i = parameter_ptr->constraint_ptr->constraint.range.max.i;
  1073. return;
  1074. case JackParamUInt:
  1075. min_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.min.ui;
  1076. max_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.max.ui;
  1077. return;
  1078. default:
  1079. jack_error("bad driver parameter type %i (range constraint)", (int)parameter_ptr->type);
  1080. assert(0);
  1081. }
  1082. }
  1083. bool jackctl_parameter_constraint_is_strict(jackctl_parameter_t * parameter_ptr)
  1084. {
  1085. return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_STRICT) != 0;
  1086. }
  1087. bool jackctl_parameter_constraint_is_fake_value(jackctl_parameter_t * parameter_ptr)
  1088. {
  1089. return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0;
  1090. }
  1091. jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter_t *parameter_ptr)
  1092. {
  1093. return parameter_ptr->type;
  1094. }
  1095. char jackctl_parameter_get_id(jackctl_parameter_t * parameter_ptr)
  1096. {
  1097. return parameter_ptr->id;
  1098. }
  1099. bool jackctl_parameter_is_set(jackctl_parameter_t *parameter_ptr)
  1100. {
  1101. return parameter_ptr->is_set;
  1102. }
  1103. union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter_t *parameter_ptr)
  1104. {
  1105. return *(parameter_ptr->value_ptr);
  1106. }
  1107. bool jackctl_parameter_reset(jackctl_parameter_t *parameter_ptr)
  1108. {
  1109. if (!parameter_ptr->is_set)
  1110. {
  1111. return true;
  1112. }
  1113. parameter_ptr->is_set = false;
  1114. *parameter_ptr->value_ptr = *parameter_ptr->default_value_ptr;
  1115. return true;
  1116. }
  1117. bool jackctl_parameter_set_value(jackctl_parameter_t *parameter_ptr, const union jackctl_parameter_value * value_ptr)
  1118. {
  1119. bool new_driver_parameter;
  1120. /* for driver parameters, set the parameter by adding jack_driver_param_t in the set_parameters list */
  1121. if (parameter_ptr->driver_ptr != NULL)
  1122. {
  1123. /* jack_info("setting driver parameter %p ...", parameter_ptr); */
  1124. new_driver_parameter = parameter_ptr->driver_parameter_ptr == NULL;
  1125. if (new_driver_parameter)
  1126. {
  1127. /* jack_info("new driver parameter..."); */
  1128. parameter_ptr->driver_parameter_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t));
  1129. if (parameter_ptr->driver_parameter_ptr == NULL)
  1130. {
  1131. jack_error ("Allocation of jack_driver_param_t structure failed");
  1132. return false;
  1133. }
  1134. parameter_ptr->driver_parameter_ptr->character = parameter_ptr->id;
  1135. parameter_ptr->driver_ptr->set_parameters = jack_slist_append(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr);
  1136. }
  1137. switch (parameter_ptr->type)
  1138. {
  1139. case JackParamInt:
  1140. parameter_ptr->driver_parameter_ptr->value.i = value_ptr->i;
  1141. break;
  1142. case JackParamUInt:
  1143. parameter_ptr->driver_parameter_ptr->value.ui = value_ptr->ui;
  1144. break;
  1145. case JackParamChar:
  1146. parameter_ptr->driver_parameter_ptr->value.c = value_ptr->c;
  1147. break;
  1148. case JackParamString:
  1149. strcpy(parameter_ptr->driver_parameter_ptr->value.str, value_ptr->str);
  1150. break;
  1151. case JackParamBool:
  1152. parameter_ptr->driver_parameter_ptr->value.i = value_ptr->b;
  1153. break;
  1154. default:
  1155. jack_error("unknown parameter type %i", (int)parameter_ptr->type);
  1156. assert(0);
  1157. if (new_driver_parameter)
  1158. {
  1159. parameter_ptr->driver_ptr->set_parameters = jack_slist_remove(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr);
  1160. }
  1161. return false;
  1162. }
  1163. }
  1164. parameter_ptr->is_set = true;
  1165. *parameter_ptr->value_ptr = *value_ptr;
  1166. return true;
  1167. }
  1168. union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter_t *parameter_ptr)
  1169. {
  1170. return *(parameter_ptr->default_value_ptr);
  1171. }
  1172. // Internals clients
  1173. const JSList * jackctl_server_get_internals_list(jackctl_server_t *server_ptr)
  1174. {
  1175. return server_ptr->internals;
  1176. }
  1177. const char * jackctl_internal_get_name(jackctl_internal_t *internal_ptr)
  1178. {
  1179. return internal_ptr->desc_ptr->name;
  1180. }
  1181. const JSList * jackctl_internal_get_parameters(jackctl_internal_t *internal_ptr)
  1182. {
  1183. return internal_ptr->parameters;
  1184. }
  1185. bool jackctl_server_load_internal(
  1186. jackctl_server_t * server_ptr,
  1187. jackctl_internal_t * internal)
  1188. {
  1189. #if 0
  1190. int status;
  1191. if (server_ptr->engine != NULL) {
  1192. server_ptr->engine->InternalClientLoad(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status);
  1193. return (internal->refnum > 0);
  1194. } else {
  1195. return false;
  1196. }
  1197. #endif
  1198. }
  1199. bool jackctl_server_unload_internal(
  1200. jackctl_server_t * server_ptr,
  1201. jackctl_internal_t * internal)
  1202. {
  1203. #if 0
  1204. int status;
  1205. if (server_ptr->engine != NULL && internal->refnum > 0) {
  1206. return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0);
  1207. } else {
  1208. return false;
  1209. }
  1210. #endif
  1211. }
  1212. bool jackctl_server_add_slave(jackctl_server_t * server_ptr, jackctl_driver_t * driver_ptr)
  1213. {
  1214. #if 0
  1215. if (server_ptr->engine != NULL) {
  1216. driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters);
  1217. return (driver_ptr->info != 0);
  1218. } else {
  1219. return false;
  1220. }
  1221. #endif
  1222. }
  1223. bool jackctl_server_remove_slave(jackctl_server_t * server_ptr, jackctl_driver_t * driver_ptr)
  1224. {
  1225. #if 0
  1226. if (server_ptr->engine != NULL) {
  1227. server_ptr->engine->RemoveSlave(driver_ptr->info);
  1228. delete driver_ptr->info;
  1229. return true;
  1230. } else {
  1231. return false;
  1232. }
  1233. #endif
  1234. }
  1235. bool jackctl_server_switch_master(jackctl_server_t * server_ptr, jackctl_driver_t * driver_ptr)
  1236. {
  1237. jack_driver_t *old_driver;
  1238. if (server_ptr->engine == NULL)
  1239. goto fail_nostart;
  1240. old_driver = server_ptr->engine->driver;
  1241. if (old_driver)
  1242. {
  1243. old_driver->stop (old_driver );
  1244. old_driver->detach (old_driver, server_ptr->engine);
  1245. pthread_mutex_lock (&server_ptr->engine->request_lock);
  1246. jack_lock_graph (server_ptr->engine);
  1247. jack_remove_client (server_ptr->engine, old_driver->internal_client);
  1248. jack_unlock_graph (server_ptr->engine);
  1249. pthread_mutex_unlock (&server_ptr->engine->request_lock);
  1250. jack_stop_watchdog (server_ptr->engine);
  1251. server_ptr->engine->driver = NULL;
  1252. jack_driver_unload (old_driver);
  1253. }
  1254. if (jack_engine_load_driver (server_ptr->engine, driver_ptr->desc_ptr, driver_ptr->set_parameters))
  1255. {
  1256. jack_error ("cannot load driver module %s", driver_ptr->desc_ptr->name);
  1257. goto fail_nodriver;
  1258. }
  1259. if (server_ptr->engine->driver->start (server_ptr->engine->driver) != 0) {
  1260. jack_error ("cannot start driver");
  1261. goto fail_nostart;
  1262. }
  1263. return true;
  1264. fail_nodriver:
  1265. jack_error ("could not initialise new driver, leaving without driver");
  1266. fail_nostart:
  1267. return false;
  1268. }