jack2 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.

779 lines
21KB

  1. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  2. /*
  3. Copyright (C) 2007,2008,2010,2011 Nedko Arnaudov
  4. Copyright (C) 2007-2008 Juuso Alasuutari
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #if defined(HAVE_CONFIG_H)
  17. #include "config.h"
  18. #endif
  19. #include <stdint.h>
  20. #include <string.h>
  21. #include <dbus/dbus.h>
  22. #include <assert.h>
  23. #include <unistd.h>
  24. #include "controller.h"
  25. #include "controller_internal.h"
  26. #include "xml.h"
  27. #include "reserve.h"
  28. struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] =
  29. {
  30. &g_jack_controller_iface_introspectable,
  31. &g_jack_controller_iface_control,
  32. &g_jack_controller_iface_configure,
  33. &g_jack_controller_iface_patchbay,
  34. &g_jack_controller_iface_session_manager,
  35. &g_jack_controller_iface_transport,
  36. NULL
  37. };
  38. static
  39. jackctl_driver_t *
  40. jack_controller_find_driver(
  41. jackctl_server_t *server,
  42. const char *driver_name)
  43. {
  44. const JSList * node_ptr;
  45. node_ptr = jackctl_server_get_drivers_list(server);
  46. while (node_ptr)
  47. {
  48. if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0)
  49. {
  50. return node_ptr->data;
  51. }
  52. node_ptr = jack_slist_next(node_ptr);
  53. }
  54. return NULL;
  55. }
  56. static bool jack_controller_check_slave_driver(struct jack_controller * controller_ptr, const char * name)
  57. {
  58. struct list_head * node_ptr;
  59. struct jack_controller_slave_driver * driver_ptr;
  60. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  61. {
  62. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  63. if (strcmp(name, driver_ptr->name) == 0)
  64. {
  65. return true;
  66. }
  67. }
  68. return false;
  69. }
  70. static bool jack_controller_load_slave_drivers(struct jack_controller * controller_ptr)
  71. {
  72. struct list_head * node_ptr;
  73. struct jack_controller_slave_driver * driver_ptr;
  74. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  75. {
  76. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  77. assert(driver_ptr->handle != NULL);
  78. assert(!driver_ptr->loaded);
  79. if (!jackctl_server_add_slave(controller_ptr->server, driver_ptr->handle))
  80. {
  81. jack_error("Driver \"%s\" cannot be loaded", driver_ptr->name);
  82. return false;
  83. }
  84. driver_ptr->loaded = true;
  85. }
  86. return true;
  87. }
  88. static void jack_controller_unload_slave_drivers(struct jack_controller * controller_ptr)
  89. {
  90. struct list_head * node_ptr;
  91. struct jack_controller_slave_driver * driver_ptr;
  92. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  93. {
  94. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  95. if (driver_ptr->loaded)
  96. {
  97. jackctl_server_remove_slave(controller_ptr->server, driver_ptr->handle);
  98. driver_ptr->loaded = false;
  99. }
  100. }
  101. }
  102. static void jack_controller_remove_slave_drivers(struct jack_controller * controller_ptr)
  103. {
  104. struct jack_controller_slave_driver * driver_ptr;
  105. while (!list_empty(&controller_ptr->slave_drivers))
  106. {
  107. driver_ptr = list_entry(controller_ptr->slave_drivers.next, struct jack_controller_slave_driver, siblings);
  108. assert(!driver_ptr->loaded);
  109. list_del(&driver_ptr->siblings);
  110. free(driver_ptr->name);
  111. free(driver_ptr);
  112. }
  113. controller_ptr->slave_drivers_vparam_value.str[0] = 0;
  114. }
  115. static
  116. jackctl_internal_t *
  117. jack_controller_find_internal(
  118. jackctl_server_t *server,
  119. const char *internal_name)
  120. {
  121. const JSList * node_ptr;
  122. node_ptr = jackctl_server_get_internals_list(server);
  123. while (node_ptr)
  124. {
  125. if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0)
  126. {
  127. return node_ptr->data;
  128. }
  129. node_ptr = jack_slist_next(node_ptr);
  130. }
  131. return NULL;
  132. }
  133. bool
  134. jack_controller_select_driver(
  135. struct jack_controller * controller_ptr,
  136. const char * driver_name)
  137. {
  138. if (!jack_params_set_driver(controller_ptr->params, driver_name))
  139. {
  140. return false;
  141. }
  142. jack_info("driver \"%s\" selected", driver_name);
  143. return true;
  144. }
  145. static
  146. int
  147. jack_controller_xrun(void * arg)
  148. {
  149. ((struct jack_controller *)arg)->xruns++;
  150. return 0;
  151. }
  152. bool
  153. jack_controller_start_server(
  154. struct jack_controller * controller_ptr,
  155. void *dbus_call_context_ptr)
  156. {
  157. int ret;
  158. jack_info("Starting jack server...");
  159. assert(!controller_ptr->started); /* should be ensured by caller */
  160. controller_ptr->xruns = 0;
  161. if (!jackctl_server_open(
  162. controller_ptr->server,
  163. jack_params_get_driver(controller_ptr->params)))
  164. {
  165. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to open server");
  166. goto fail;
  167. }
  168. jack_controller_load_slave_drivers(controller_ptr);
  169. if (!jackctl_server_start(
  170. controller_ptr->server))
  171. {
  172. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server");
  173. goto fail_close_server;
  174. }
  175. controller_ptr->client = jack_client_open(
  176. "dbusapi",
  177. JackNoStartServer,
  178. NULL);
  179. if (controller_ptr->client == NULL)
  180. {
  181. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client");
  182. goto fail_stop_server;
  183. }
  184. ret = jack_set_xrun_callback(controller_ptr->client, jack_controller_xrun, controller_ptr);
  185. if (ret != 0)
  186. {
  187. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret);
  188. goto fail_close_client;
  189. }
  190. if (!jack_controller_patchbay_init(controller_ptr))
  191. {
  192. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to initialize patchbay district");
  193. goto fail_close_client;
  194. }
  195. ret = jack_activate(controller_ptr->client);
  196. if (ret != 0)
  197. {
  198. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret);
  199. goto fail_patchbay_uninit;
  200. }
  201. controller_ptr->started = true;
  202. return TRUE;
  203. fail_patchbay_uninit:
  204. jack_controller_patchbay_uninit(controller_ptr);
  205. fail_close_client:
  206. ret = jack_client_close(controller_ptr->client);
  207. if (ret != 0)
  208. {
  209. jack_error("jack_client_close() failed with error %d", ret);
  210. }
  211. controller_ptr->client = NULL;
  212. fail_stop_server:
  213. if (!jackctl_server_stop(controller_ptr->server))
  214. {
  215. jack_error("failed to stop jack server");
  216. }
  217. fail_close_server:
  218. jack_controller_unload_slave_drivers(controller_ptr);
  219. if (!jackctl_server_close(controller_ptr->server))
  220. {
  221. jack_error("failed to close jack server");
  222. }
  223. fail:
  224. return FALSE;
  225. }
  226. bool
  227. jack_controller_stop_server(
  228. struct jack_controller * controller_ptr,
  229. void *dbus_call_context_ptr)
  230. {
  231. int ret;
  232. pthread_mutex_lock(&controller_ptr->lock);
  233. if (!list_empty(&controller_ptr->session_pending_commands))
  234. {
  235. pthread_mutex_unlock(&controller_ptr->lock);
  236. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Refusing to stop JACK server because of pending session commands");
  237. return false;
  238. }
  239. pthread_mutex_unlock(&controller_ptr->lock);
  240. jack_info("Stopping jack server...");
  241. assert(controller_ptr->started); /* should be ensured by caller */
  242. ret = jack_deactivate(controller_ptr->client);
  243. if (ret != 0)
  244. {
  245. jack_error("failed to deactivate dbusapi jack client. error is %d", ret);
  246. }
  247. jack_controller_patchbay_uninit(controller_ptr);
  248. ret = jack_client_close(controller_ptr->client);
  249. if (ret != 0)
  250. {
  251. jack_error("jack_client_close() failed with error %d", ret);
  252. }
  253. controller_ptr->client = NULL;
  254. if (!jackctl_server_stop(controller_ptr->server))
  255. {
  256. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to stop server");
  257. return FALSE;
  258. }
  259. jack_controller_unload_slave_drivers(controller_ptr);
  260. if (!jackctl_server_close(controller_ptr->server))
  261. {
  262. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to close server");
  263. return FALSE;
  264. }
  265. controller_ptr->started = false;
  266. return TRUE;
  267. }
  268. bool
  269. jack_controller_switch_master(
  270. struct jack_controller * controller_ptr,
  271. void *dbus_call_context_ptr)
  272. {
  273. assert(controller_ptr->started); /* should be ensured by caller */
  274. if (!jackctl_server_switch_master(
  275. controller_ptr->server,
  276. jack_params_get_driver(controller_ptr->params)))
  277. {
  278. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to switch master");
  279. controller_ptr->started = false;
  280. return FALSE;
  281. }
  282. return TRUE;
  283. }
  284. #define DEVICE_MAX 2
  285. typedef struct reserved_audio_device {
  286. char device_name[64];
  287. rd_device * reserved_device;
  288. } reserved_audio_device;
  289. int g_device_count = 0;
  290. static reserved_audio_device g_reserved_device[DEVICE_MAX];
  291. static
  292. bool
  293. on_device_acquire(const char * device_name)
  294. {
  295. int ret;
  296. DBusError error;
  297. ret = rd_acquire(
  298. &g_reserved_device[g_device_count].reserved_device,
  299. g_connection,
  300. device_name,
  301. "Jack audio server",
  302. INT32_MAX,
  303. NULL,
  304. &error);
  305. if (ret < 0)
  306. {
  307. jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret)));
  308. return false;
  309. }
  310. strcpy(g_reserved_device[g_device_count].device_name, device_name);
  311. g_device_count++;
  312. jack_info("Acquired audio card %s", device_name);
  313. return true;
  314. }
  315. static
  316. void
  317. on_device_release(const char * device_name)
  318. {
  319. int i;
  320. // Look for corresponding reserved device
  321. for (i = 0; i < DEVICE_MAX; i++) {
  322. if (strcmp(g_reserved_device[i].device_name, device_name) == 0)
  323. break;
  324. }
  325. if (i < DEVICE_MAX) {
  326. jack_info("Released audio card %s", device_name);
  327. rd_release(g_reserved_device[i].reserved_device);
  328. } else {
  329. jack_error("Audio card %s not found!!", device_name);
  330. }
  331. g_device_count--;
  332. }
  333. #define controller_ptr ((struct jack_controller *)obj)
  334. static bool slave_drivers_parameter_is_set(void * obj)
  335. {
  336. return controller_ptr->slave_drivers_set;
  337. }
  338. static bool slave_drivers_parameter_reset(void * obj)
  339. {
  340. if (controller_ptr->started)
  341. {
  342. jack_error("Cannot modify slave-drivers when server is started");
  343. return false;
  344. }
  345. jack_controller_remove_slave_drivers(controller_ptr);
  346. controller_ptr->slave_drivers_set = false;
  347. return true;
  348. }
  349. static union jackctl_parameter_value slave_drivers_parameter_get_value(void * obj)
  350. {
  351. return controller_ptr->slave_drivers_vparam_value;
  352. }
  353. static bool slave_drivers_parameter_set_value(void * obj, const union jackctl_parameter_value * value_ptr)
  354. {
  355. char * buffer;
  356. char * save;
  357. const char * token;
  358. struct list_head old_list;
  359. struct list_head new_list;
  360. union jackctl_parameter_value old_value;
  361. union jackctl_parameter_value new_value;
  362. bool old_set;
  363. if (controller_ptr->started)
  364. {
  365. jack_error("Cannot modify slave-drivers when server is started");
  366. return false;
  367. }
  368. old_set = controller_ptr->slave_drivers_set;
  369. old_value = controller_ptr->slave_drivers_vparam_value;
  370. controller_ptr->slave_drivers_vparam_value.str[0] = 0;
  371. old_list = controller_ptr->slave_drivers;
  372. INIT_LIST_HEAD(&controller_ptr->slave_drivers);
  373. buffer = strdup(value_ptr->str);
  374. if (buffer == NULL)
  375. {
  376. jack_error("strdup() failed.");
  377. return false;
  378. }
  379. token = strtok_r(buffer, ",", &save);
  380. while (token)
  381. {
  382. //jack_info("slave driver '%s'", token);
  383. if (!jack_controller_add_slave_driver(controller_ptr, token))
  384. {
  385. jack_controller_remove_slave_drivers(controller_ptr);
  386. controller_ptr->slave_drivers = old_list;
  387. controller_ptr->slave_drivers_vparam_value = old_value;
  388. controller_ptr->slave_drivers_set = old_set;
  389. free(buffer);
  390. return false;
  391. }
  392. token = strtok_r(NULL, ",", &save);
  393. }
  394. new_value = controller_ptr->slave_drivers_vparam_value;
  395. new_list = controller_ptr->slave_drivers;
  396. controller_ptr->slave_drivers = old_list;
  397. jack_controller_remove_slave_drivers(controller_ptr);
  398. controller_ptr->slave_drivers_vparam_value = new_value;
  399. controller_ptr->slave_drivers = new_list;
  400. controller_ptr->slave_drivers_set = true;
  401. free(buffer);
  402. return true;
  403. }
  404. static union jackctl_parameter_value slave_drivers_parameter_get_default_value(void * obj)
  405. {
  406. union jackctl_parameter_value value;
  407. value.str[0] = 0;
  408. return value;
  409. }
  410. #undef controller_ptr
  411. void *
  412. jack_controller_create(
  413. DBusConnection *connection)
  414. {
  415. int error;
  416. struct jack_controller *controller_ptr;
  417. const char * address[PARAM_ADDRESS_SIZE];
  418. DBusObjectPathVTable vtable =
  419. {
  420. jack_dbus_message_handler_unregister,
  421. jack_dbus_message_handler,
  422. NULL
  423. };
  424. controller_ptr = malloc(sizeof(struct jack_controller));
  425. if (!controller_ptr)
  426. {
  427. jack_error("Ran out of memory trying to allocate struct jack_controller");
  428. goto fail;
  429. }
  430. error = pthread_mutex_init(&controller_ptr->lock, NULL);
  431. if (error != 0)
  432. {
  433. jack_error("Failed to initialize mutex. error %d", error);
  434. goto fail_free;
  435. }
  436. INIT_LIST_HEAD(&controller_ptr->session_pending_commands);
  437. controller_ptr->server = jackctl_server_create(on_device_acquire, on_device_release);
  438. if (controller_ptr->server == NULL)
  439. {
  440. jack_error("Failed to create server object");
  441. goto fail_uninit_mutex;
  442. }
  443. controller_ptr->params = jack_params_create(controller_ptr->server);
  444. if (controller_ptr->params == NULL)
  445. {
  446. jack_error("Failed to initialize parameter tree");
  447. goto fail_destroy_server;
  448. }
  449. controller_ptr->client = NULL;
  450. controller_ptr->started = false;
  451. INIT_LIST_HEAD(&controller_ptr->slave_drivers);
  452. controller_ptr->slave_drivers_set = false;
  453. controller_ptr->slave_drivers_vparam_value.str[0] = 0;
  454. controller_ptr->slave_drivers_vparam.obj = controller_ptr;
  455. controller_ptr->slave_drivers_vparam.vtable.is_set = slave_drivers_parameter_is_set;
  456. controller_ptr->slave_drivers_vparam.vtable.reset = slave_drivers_parameter_reset;
  457. controller_ptr->slave_drivers_vparam.vtable.get_value = slave_drivers_parameter_get_value;
  458. controller_ptr->slave_drivers_vparam.vtable.set_value = slave_drivers_parameter_set_value;
  459. controller_ptr->slave_drivers_vparam.vtable.get_default_value = slave_drivers_parameter_get_default_value;
  460. controller_ptr->slave_drivers_vparam.type = JackParamString;
  461. controller_ptr->slave_drivers_vparam.name = "slave-drivers";
  462. controller_ptr->slave_drivers_vparam.short_decr = "Slave drivers to use";
  463. controller_ptr->slave_drivers_vparam.long_descr = "A comma separated list of slave drivers";
  464. controller_ptr->slave_drivers_vparam.constraint_flags = 0;
  465. address[0] = PTNODE_ENGINE;
  466. address[1] = NULL;
  467. jack_params_add_parameter(controller_ptr->params, address, true, &controller_ptr->slave_drivers_vparam);
  468. controller_ptr->dbus_descriptor.context = controller_ptr;
  469. controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
  470. if (!dbus_connection_register_object_path(
  471. connection,
  472. JACK_CONTROLLER_OBJECT_PATH,
  473. &vtable,
  474. &controller_ptr->dbus_descriptor))
  475. {
  476. jack_error("Ran out of memory trying to register D-Bus object path");
  477. goto fail_destroy_params;
  478. }
  479. jack_controller_settings_load(controller_ptr);
  480. return controller_ptr;
  481. fail_destroy_params:
  482. jack_params_destroy(controller_ptr->params);
  483. fail_destroy_server:
  484. jackctl_server_destroy(controller_ptr->server);
  485. fail_uninit_mutex:
  486. pthread_mutex_destroy(&controller_ptr->lock);
  487. fail_free:
  488. free(controller_ptr);
  489. fail:
  490. return NULL;
  491. }
  492. bool
  493. jack_controller_add_slave_driver(
  494. struct jack_controller * controller_ptr,
  495. const char * driver_name)
  496. {
  497. jackctl_driver_t * driver;
  498. struct jack_controller_slave_driver * driver_ptr;
  499. size_t len_old;
  500. size_t len_new;
  501. len_old = strlen(controller_ptr->slave_drivers_vparam_value.str);
  502. len_new = strlen(driver_name);
  503. if (len_old + len_new + 2 > sizeof(controller_ptr->slave_drivers_vparam_value.str))
  504. {
  505. jack_error("No more space for slave drivers.");
  506. return false;
  507. }
  508. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  509. if (driver == NULL)
  510. {
  511. jack_error("Unknown driver \"%s\"", driver_name);
  512. return false;
  513. }
  514. if (jack_controller_check_slave_driver(controller_ptr, driver_name))
  515. {
  516. jack_info("Driver \"%s\" is already slave", driver_name);
  517. return true;
  518. }
  519. driver_ptr = malloc(sizeof(struct jack_controller_slave_driver));
  520. if (driver_ptr == NULL)
  521. {
  522. jack_error("malloc() failed to allocate jack_controller_slave_driver struct");
  523. return false;
  524. }
  525. driver_ptr->name = strdup(driver_name);
  526. if (driver_ptr->name == NULL)
  527. {
  528. jack_error("strdup() failed for slave driver name \"%s\"", driver_name);
  529. free(driver_ptr);
  530. return false;
  531. }
  532. driver_ptr->handle = driver;
  533. driver_ptr->loaded = false;
  534. jack_info("driver \"%s\" set as slave", driver_name);
  535. list_add_tail(&driver_ptr->siblings, &controller_ptr->slave_drivers);
  536. if (len_old != 0)
  537. {
  538. controller_ptr->slave_drivers_vparam_value.str[len_old++] = ',';
  539. }
  540. memcpy(controller_ptr->slave_drivers_vparam_value.str + len_old, driver_name, len_new + 1);
  541. controller_ptr->slave_drivers_set = true;
  542. return true;
  543. }
  544. bool
  545. jack_controller_remove_slave_driver(
  546. struct jack_controller * controller_ptr,
  547. const char * driver_name)
  548. {
  549. struct list_head * node_ptr;
  550. struct jack_controller_slave_driver * driver_ptr;
  551. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  552. {
  553. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  554. if (strcmp(driver_ptr->name, driver_name) == 0)
  555. {
  556. list_del(&driver_ptr->siblings);
  557. free(driver_ptr->name);
  558. free(driver_ptr);
  559. /* update the slave-drivers param value */
  560. controller_ptr->slave_drivers_vparam_value.str[0] = 0;
  561. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  562. {
  563. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  564. if (controller_ptr->slave_drivers_vparam_value.str[0] != 0)
  565. {
  566. strcat(controller_ptr->slave_drivers_vparam_value.str, ",");
  567. }
  568. strcat(controller_ptr->slave_drivers_vparam_value.str, driver_ptr->name);
  569. }
  570. jack_info("driver \"%s\" is not slave anymore", driver_name);
  571. return true;
  572. }
  573. }
  574. return false;
  575. }
  576. bool
  577. jack_controller_load_internal(
  578. struct jack_controller *controller_ptr,
  579. const char * internal_name)
  580. {
  581. jackctl_internal_t *internal;
  582. internal = jack_controller_find_internal(controller_ptr->server, internal_name);
  583. if (internal == NULL)
  584. {
  585. return false;
  586. }
  587. jack_info("internal \"%s\" selected", internal_name);
  588. return jackctl_server_load_internal(controller_ptr->server, internal);
  589. }
  590. bool
  591. jack_controller_unload_internal(
  592. struct jack_controller *controller_ptr,
  593. const char * internal_name)
  594. {
  595. jackctl_internal_t *internal;
  596. internal = jack_controller_find_internal(controller_ptr->server, internal_name);
  597. if (internal == NULL)
  598. {
  599. return false;
  600. }
  601. jack_info("internal \"%s\" selected", internal_name);
  602. return jackctl_server_unload_internal(controller_ptr->server, internal);
  603. }
  604. #define controller_ptr ((struct jack_controller *)context)
  605. void
  606. jack_controller_destroy(
  607. void * context)
  608. {
  609. if (controller_ptr->started)
  610. {
  611. while (!jack_controller_stop_server(controller_ptr, NULL))
  612. {
  613. jack_info("jack server failed to stop, retrying in 3 seconds...");
  614. usleep(3000000);
  615. }
  616. }
  617. jack_controller_remove_slave_drivers(controller_ptr);
  618. jack_params_destroy(controller_ptr->params);
  619. jackctl_server_destroy(controller_ptr->server);
  620. pthread_mutex_destroy(&controller_ptr->lock);
  621. free(controller_ptr);
  622. }