1
/* -*- mode: c; c-file-style: "linux"; -*- */
3
Copyright (C) 2001-2003 Paul Davis
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU Lesser General Public License as published by
7
the Free Software Foundation; either version 2.1 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU Lesser General Public License for more details.
15
You should have received a copy of the GNU Lesser General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29
#include <jack/internal.h>
30
#include <jack/driver.h>
31
#include <jack/engine.h>
32
#include <jack/thread.h>
36
#endif /* USE_MLOCK */
38
static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
39
static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
40
static int dummy_write (jack_driver_t *drv,
41
jack_nframes_t nframes) { return 0; }
42
static int dummy_read (jack_driver_t *drv, jack_nframes_t nframes) { return 0; }
43
static int dummy_null_cycle (jack_driver_t *drv,
44
jack_nframes_t nframes) { return 0; }
45
static int dummy_bufsize (jack_driver_t *drv,
46
jack_nframes_t nframes) {return 0;}
47
static int dummy_stop (jack_driver_t *drv) { return 0; }
48
static int dummy_start (jack_driver_t *drv) { return 0; }
51
jack_driver_init (jack_driver_t *driver)
53
memset (driver, 0, sizeof (*driver));
55
driver->attach = dummy_attach;
56
driver->detach = dummy_detach;
57
driver->write = dummy_write;
58
driver->read = dummy_read;
59
driver->null_cycle = dummy_null_cycle;
60
driver->bufsize = dummy_bufsize;
61
driver->start = dummy_start;
62
driver->stop = dummy_stop;
67
/****************************
68
*** Non-Threaded Drivers ***
69
****************************/
71
static int dummy_nt_run_cycle (jack_driver_nt_t *drv) { return 0; }
72
static int dummy_nt_attach (jack_driver_nt_t *drv) { return 0; }
73
static int dummy_nt_detach (jack_driver_nt_t *drv) { return 0; }
77
* These are used in driver->nt_run for controlling whether or not
78
* driver->engine->driver_exit() gets called (EXIT = call it, PAUSE = don't)
80
#define DRIVER_NT_RUN 0
81
#define DRIVER_NT_EXIT 1
82
#define DRIVER_NT_PAUSE 2
83
#define DRIVER_NT_DYING 3
86
jack_driver_nt_attach (jack_driver_nt_t * driver, jack_engine_t * engine)
88
driver->engine = engine;
89
return driver->nt_attach (driver);
93
jack_driver_nt_detach (jack_driver_nt_t * driver, jack_engine_t * engine)
97
ret = driver->nt_detach (driver);
98
driver->engine = NULL;
104
jack_driver_nt_thread (void * arg)
106
jack_driver_nt_t * driver = (jack_driver_nt_t *) arg;
110
/* This thread may start running before pthread_create()
111
* actually stores the driver->nt_thread value. It's safer to
112
* store it here as well.
115
driver->nt_thread = pthread_self();
117
pthread_mutex_lock (&driver->nt_run_lock);
119
while ((run = driver->nt_run) == DRIVER_NT_RUN) {
120
pthread_mutex_unlock (&driver->nt_run_lock);
122
if ((rc = driver->nt_run_cycle (driver)) != 0) {
123
jack_error ("DRIVER NT: could not run driver cycle");
127
pthread_mutex_lock (&driver->nt_run_lock);
130
pthread_mutex_unlock (&driver->nt_run_lock);
134
driver->nt_run = DRIVER_NT_DYING;
135
driver->engine->driver_exit (driver->engine);
141
jack_driver_nt_start (jack_driver_nt_t * driver)
145
/* stop the new thread from really starting until the driver has
149
pthread_mutex_lock (&driver->nt_run_lock);
150
driver->nt_run = DRIVER_NT_RUN;
152
if ((err = jack_client_create_thread (NULL,
154
driver->engine->rtpriority,
155
driver->engine->control->real_time,
156
jack_driver_nt_thread, driver)) != 0) {
157
jack_error ("DRIVER NT: could not start driver thread!");
161
if ((err = driver->nt_start (driver)) != 0) {
162
/* make the thread run and exit immediately */
163
driver->nt_run = DRIVER_NT_EXIT;
164
pthread_mutex_unlock (&driver->nt_run_lock);
165
jack_error ("DRIVER NT: could not start driver");
169
/* let the thread run, since the underlying "device" has now been started */
171
pthread_mutex_unlock (&driver->nt_run_lock);
177
jack_driver_nt_do_stop (jack_driver_nt_t * driver, int run)
181
pthread_mutex_lock (&driver->nt_run_lock);
182
if(driver->nt_run != DRIVER_NT_DYING) {
183
driver->nt_run = run;
185
pthread_mutex_unlock (&driver->nt_run_lock);
187
/* detect when called while the thread is shutting itself down */
188
if (driver->nt_thread && driver->nt_run != DRIVER_NT_DYING
189
&& (err = pthread_join (driver->nt_thread, NULL)) != 0) {
190
jack_error ("DRIVER NT: error waiting for driver thread: %s",
195
if ((err = driver->nt_stop (driver)) != 0) {
196
jack_error ("DRIVER NT: error stopping driver");
204
jack_driver_nt_stop (jack_driver_nt_t * driver)
206
return jack_driver_nt_do_stop (driver, DRIVER_NT_EXIT);
210
jack_driver_nt_bufsize (jack_driver_nt_t * driver, jack_nframes_t nframes)
215
err = jack_driver_nt_do_stop (driver, DRIVER_NT_PAUSE);
217
jack_error ("DRIVER NT: could not stop driver to change buffer size");
218
driver->engine->driver_exit (driver->engine);
222
ret = driver->nt_bufsize (driver, nframes);
224
err = jack_driver_nt_start (driver);
226
jack_error ("DRIVER NT: could not restart driver during buffer size change");
227
driver->engine->driver_exit (driver->engine);
235
jack_driver_nt_init (jack_driver_nt_t * driver)
237
memset (driver, 0, sizeof (*driver));
239
jack_driver_init ((jack_driver_t *) driver);
241
driver->attach = (JackDriverAttachFunction) jack_driver_nt_attach;
242
driver->detach = (JackDriverDetachFunction) jack_driver_nt_detach;
243
driver->bufsize = (JackDriverBufSizeFunction) jack_driver_nt_bufsize;
244
driver->stop = (JackDriverStopFunction) jack_driver_nt_stop;
245
driver->start = (JackDriverStartFunction) jack_driver_nt_start;
247
driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_bufsize;
248
driver->nt_start = (JackDriverNTStartFunction) dummy_start;
249
driver->nt_stop = (JackDriverNTStopFunction) dummy_stop;
250
driver->nt_attach = dummy_nt_attach;
251
driver->nt_detach = dummy_nt_detach;
252
driver->nt_run_cycle = dummy_nt_run_cycle;
255
pthread_mutex_init (&driver->nt_run_lock, NULL);
259
jack_driver_nt_finish (jack_driver_nt_t * driver)
261
pthread_mutex_destroy (&driver->nt_run_lock);