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.

264 lines
7.1KB

  1. /* -*- mode: c; c-file-style: "linux"; -*- */
  2. /*
  3. Copyright (C) 2001-2003 Paul Davis
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  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 Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include <config.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <stdarg.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <errno.h>
  23. #include <jack/thread.h>
  24. #include "internal.h"
  25. #include "driver.h"
  26. #include "engine.h"
  27. #ifdef USE_MLOCK
  28. #include <sys/mman.h>
  29. #endif /* USE_MLOCK */
  30. static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
  31. static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
  32. static int dummy_write (jack_driver_t *drv,
  33. jack_nframes_t nframes) { return 0; }
  34. static int dummy_read (jack_driver_t *drv, jack_nframes_t nframes) { return 0; }
  35. static int dummy_null_cycle (jack_driver_t *drv,
  36. jack_nframes_t nframes) { return 0; }
  37. static int dummy_bufsize (jack_driver_t *drv,
  38. jack_nframes_t nframes) {return 0;}
  39. static int dummy_stop (jack_driver_t *drv) { return 0; }
  40. static int dummy_start (jack_driver_t *drv) { return 0; }
  41. void
  42. jack_driver_init (jack_driver_t *driver)
  43. {
  44. memset (driver, 0, sizeof (*driver));
  45. driver->attach = dummy_attach;
  46. driver->detach = dummy_detach;
  47. driver->write = dummy_write;
  48. driver->read = dummy_read;
  49. driver->null_cycle = dummy_null_cycle;
  50. driver->bufsize = dummy_bufsize;
  51. driver->start = dummy_start;
  52. driver->stop = dummy_stop;
  53. }
  54. /****************************
  55. *** Non-Threaded Drivers ***
  56. ****************************/
  57. static int dummy_nt_run_cycle (jack_driver_nt_t *drv) { return 0; }
  58. static int dummy_nt_attach (jack_driver_nt_t *drv) { return 0; }
  59. static int dummy_nt_detach (jack_driver_nt_t *drv) { return 0; }
  60. /*
  61. * These are used in driver->nt_run for controlling whether or not
  62. * driver->engine->driver_exit() gets called (EXIT = call it, PAUSE = don't)
  63. */
  64. #define DRIVER_NT_RUN 0
  65. #define DRIVER_NT_EXIT 1
  66. #define DRIVER_NT_PAUSE 2
  67. #define DRIVER_NT_DYING 3
  68. static int
  69. jack_driver_nt_attach (jack_driver_nt_t * driver, jack_engine_t * engine)
  70. {
  71. driver->engine = engine;
  72. return driver->nt_attach (driver);
  73. }
  74. static int
  75. jack_driver_nt_detach (jack_driver_nt_t * driver, jack_engine_t * engine)
  76. {
  77. int ret;
  78. ret = driver->nt_detach (driver);
  79. driver->engine = NULL;
  80. return ret;
  81. }
  82. static void *
  83. jack_driver_nt_thread (void * arg)
  84. {
  85. jack_driver_nt_t * driver = (jack_driver_nt_t *) arg;
  86. int rc = 0;
  87. int run;
  88. /* This thread may start running before pthread_create()
  89. * actually stores the driver->nt_thread value. It's safer to
  90. * store it here as well.
  91. */
  92. driver->nt_thread = pthread_self();
  93. pthread_mutex_lock (&driver->nt_run_lock);
  94. while ((run = driver->nt_run) == DRIVER_NT_RUN) {
  95. pthread_mutex_unlock (&driver->nt_run_lock);
  96. if ((rc = driver->nt_run_cycle (driver)) != 0) {
  97. jack_error ("DRIVER NT: could not run driver cycle");
  98. goto out;
  99. }
  100. pthread_mutex_lock (&driver->nt_run_lock);
  101. }
  102. pthread_mutex_unlock (&driver->nt_run_lock);
  103. out:
  104. if (rc) {
  105. driver->nt_run = DRIVER_NT_DYING;
  106. driver->engine->driver_exit (driver->engine);
  107. }
  108. pthread_exit (NULL);
  109. }
  110. static int
  111. jack_driver_nt_start (jack_driver_nt_t * driver)
  112. {
  113. int err;
  114. /* stop the new thread from really starting until the driver has
  115. been started.
  116. */
  117. pthread_mutex_lock (&driver->nt_run_lock);
  118. driver->nt_run = DRIVER_NT_RUN;
  119. if ((err = jack_client_create_thread (NULL,
  120. &driver->nt_thread,
  121. driver->engine->rtpriority,
  122. driver->engine->control->real_time,
  123. jack_driver_nt_thread, driver)) != 0) {
  124. jack_error ("DRIVER NT: could not start driver thread!");
  125. return err;
  126. }
  127. if ((err = driver->nt_start (driver)) != 0) {
  128. /* make the thread run and exit immediately */
  129. driver->nt_run = DRIVER_NT_EXIT;
  130. pthread_mutex_unlock (&driver->nt_run_lock);
  131. jack_error ("DRIVER NT: could not start driver");
  132. return err;
  133. }
  134. /* let the thread run, since the underlying "device" has now been started */
  135. pthread_mutex_unlock (&driver->nt_run_lock);
  136. return 0;
  137. }
  138. static int
  139. jack_driver_nt_do_stop (jack_driver_nt_t * driver, int run)
  140. {
  141. int err;
  142. pthread_mutex_lock (&driver->nt_run_lock);
  143. if(driver->nt_run != DRIVER_NT_DYING) {
  144. driver->nt_run = run;
  145. }
  146. pthread_mutex_unlock (&driver->nt_run_lock);
  147. /* detect when called while the thread is shutting itself down */
  148. if (driver->nt_thread && driver->nt_run != DRIVER_NT_DYING
  149. && (err = pthread_join (driver->nt_thread, NULL)) != 0) {
  150. jack_error ("DRIVER NT: error waiting for driver thread: %s",
  151. strerror (err));
  152. return err;
  153. }
  154. if ((err = driver->nt_stop (driver)) != 0) {
  155. jack_error ("DRIVER NT: error stopping driver");
  156. return err;
  157. }
  158. return 0;
  159. }
  160. static int
  161. jack_driver_nt_stop (jack_driver_nt_t * driver)
  162. {
  163. return jack_driver_nt_do_stop (driver, DRIVER_NT_EXIT);
  164. }
  165. static int
  166. jack_driver_nt_bufsize (jack_driver_nt_t * driver, jack_nframes_t nframes)
  167. {
  168. int err;
  169. int ret;
  170. err = jack_driver_nt_do_stop (driver, DRIVER_NT_PAUSE);
  171. if (err) {
  172. jack_error ("DRIVER NT: could not stop driver to change buffer size");
  173. driver->engine->driver_exit (driver->engine);
  174. return err;
  175. }
  176. ret = driver->nt_bufsize (driver, nframes);
  177. err = jack_driver_nt_start (driver);
  178. if (err) {
  179. jack_error ("DRIVER NT: could not restart driver during buffer size change");
  180. driver->engine->driver_exit (driver->engine);
  181. return err;
  182. }
  183. return ret;
  184. }
  185. void
  186. jack_driver_nt_init (jack_driver_nt_t * driver)
  187. {
  188. memset (driver, 0, sizeof (*driver));
  189. jack_driver_init ((jack_driver_t *) driver);
  190. driver->attach = (JackDriverAttachFunction) jack_driver_nt_attach;
  191. driver->detach = (JackDriverDetachFunction) jack_driver_nt_detach;
  192. driver->bufsize = (JackDriverBufSizeFunction) jack_driver_nt_bufsize;
  193. driver->stop = (JackDriverStopFunction) jack_driver_nt_stop;
  194. driver->start = (JackDriverStartFunction) jack_driver_nt_start;
  195. driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_bufsize;
  196. driver->nt_start = (JackDriverNTStartFunction) dummy_start;
  197. driver->nt_stop = (JackDriverNTStopFunction) dummy_stop;
  198. driver->nt_attach = dummy_nt_attach;
  199. driver->nt_detach = dummy_nt_detach;
  200. driver->nt_run_cycle = dummy_nt_run_cycle;
  201. pthread_mutex_init (&driver->nt_run_lock, NULL);
  202. }
  203. void
  204. jack_driver_nt_finish (jack_driver_nt_t * driver)
  205. {
  206. pthread_mutex_destroy (&driver->nt_run_lock);
  207. }