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.

255 lines
6.7KB

  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/internal.h>
  24. #include <jack/driver.h>
  25. #include <jack/engine.h>
  26. #include <jack/thread.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. static int
  68. jack_driver_nt_attach (jack_driver_nt_t * driver, jack_engine_t * engine)
  69. {
  70. driver->engine = engine;
  71. return driver->nt_attach (driver);
  72. }
  73. static int
  74. jack_driver_nt_detach (jack_driver_nt_t * driver, jack_engine_t * engine)
  75. {
  76. int ret;
  77. ret = driver->nt_detach (driver);
  78. driver->engine = NULL;
  79. return ret;
  80. }
  81. static void *
  82. jack_driver_nt_thread (void * arg)
  83. {
  84. jack_driver_nt_t * driver = (jack_driver_nt_t *) arg;
  85. int rc = 0;
  86. int run;
  87. /* This thread may start running before pthread_create()
  88. * actually stores the driver->nt_thread value. It's safer to
  89. * store it here as well.
  90. */
  91. driver->nt_thread = pthread_self();
  92. pthread_mutex_lock (&driver->nt_run_lock);
  93. while ((run = driver->nt_run) == DRIVER_NT_RUN) {
  94. pthread_mutex_unlock (&driver->nt_run_lock);
  95. if ((rc = driver->nt_run_cycle (driver)) != 0) {
  96. jack_error ("DRIVER NT: could not run driver cycle");
  97. goto out;
  98. }
  99. pthread_mutex_lock (&driver->nt_run_lock);
  100. }
  101. pthread_mutex_unlock (&driver->nt_run_lock);
  102. out:
  103. if (rc) {
  104. driver->engine->driver_exit (driver->engine);
  105. }
  106. pthread_exit (NULL);
  107. }
  108. static int
  109. jack_driver_nt_start (jack_driver_nt_t * driver)
  110. {
  111. int err;
  112. /* stop the new thread from really starting until the driver has
  113. been started.
  114. */
  115. pthread_mutex_lock (&driver->nt_run_lock);
  116. driver->nt_run = DRIVER_NT_RUN;
  117. if ((err = jack_client_create_thread (NULL,
  118. &driver->nt_thread,
  119. driver->engine->rtpriority,
  120. driver->engine->control->real_time,
  121. jack_driver_nt_thread, driver)) != 0) {
  122. jack_error ("DRIVER NT: could not start driver thread!");
  123. driver->nt_stop (driver);
  124. return err;
  125. }
  126. if ((err = driver->nt_start (driver)) != 0) {
  127. jack_error ("DRIVER NT: could not start driver");
  128. return err;
  129. }
  130. /* let the thread run, since the underlying "device" has now been started */
  131. pthread_mutex_unlock (&driver->nt_run_lock);
  132. return 0;
  133. }
  134. static int
  135. jack_driver_nt_do_stop (jack_driver_nt_t * driver, int run)
  136. {
  137. int err;
  138. pthread_mutex_lock (&driver->nt_run_lock);
  139. driver->nt_run = run;
  140. pthread_mutex_unlock (&driver->nt_run_lock);
  141. if ((err = pthread_join (driver->nt_thread, NULL)) != 0) {
  142. jack_error ("DRIVER NT: error waiting for driver thread: %s",
  143. strerror (err));
  144. return err;
  145. }
  146. if ((err = driver->nt_stop (driver)) != 0) {
  147. jack_error ("DRIVER NT: error stopping driver");
  148. return err;
  149. }
  150. return 0;
  151. }
  152. static int
  153. jack_driver_nt_stop (jack_driver_nt_t * driver)
  154. {
  155. return jack_driver_nt_do_stop (driver, DRIVER_NT_EXIT);
  156. }
  157. static int
  158. jack_driver_nt_bufsize (jack_driver_nt_t * driver, jack_nframes_t nframes)
  159. {
  160. int err;
  161. int ret;
  162. err = jack_driver_nt_do_stop (driver, DRIVER_NT_PAUSE);
  163. if (err) {
  164. jack_error ("DRIVER NT: could not stop driver to change buffer size");
  165. driver->engine->driver_exit (driver->engine);
  166. return err;
  167. }
  168. ret = driver->nt_bufsize (driver, nframes);
  169. err = jack_driver_nt_start (driver);
  170. if (err) {
  171. jack_error ("DRIVER NT: could not restart driver during buffer size change");
  172. driver->engine->driver_exit (driver->engine);
  173. return err;
  174. }
  175. return ret;
  176. }
  177. void
  178. jack_driver_nt_init (jack_driver_nt_t * driver)
  179. {
  180. memset (driver, 0, sizeof (*driver));
  181. jack_driver_init ((jack_driver_t *) driver);
  182. driver->attach = (JackDriverAttachFunction) jack_driver_nt_attach;
  183. driver->detach = (JackDriverDetachFunction) jack_driver_nt_detach;
  184. driver->bufsize = (JackDriverBufSizeFunction) jack_driver_nt_bufsize;
  185. driver->stop = (JackDriverStartFunction) jack_driver_nt_stop;
  186. driver->start = (JackDriverStopFunction) jack_driver_nt_start;
  187. driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_bufsize;
  188. driver->nt_start = (JackDriverNTStartFunction) dummy_start;
  189. driver->nt_stop = (JackDriverNTStopFunction) dummy_stop;
  190. driver->nt_attach = dummy_nt_attach;
  191. driver->nt_detach = dummy_nt_detach;
  192. driver->nt_run_cycle = dummy_nt_run_cycle;
  193. pthread_mutex_init (&driver->nt_run_lock, NULL);
  194. }
  195. void
  196. jack_driver_nt_finish (jack_driver_nt_t * driver)
  197. {
  198. pthread_mutex_destroy (&driver->nt_run_lock);
  199. }