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.

828 lines
22KB

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