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
);