WASAPI: simplify and fix device thread logic

closes #5
This commit is contained in:
Andrew Kelley 2015-09-01 17:00:13 -07:00
parent c14d61fa32
commit 7b2a10f7e5
2 changed files with 30 additions and 11 deletions

View file

@ -949,18 +949,24 @@ static void device_thread_run(void *arg) {
return; return;
} }
soundio_os_mutex_lock(siw->scan_devices_mutex);
for (;;) { for (;;) {
if (!siw->abort_flag.test_and_set()) if (siw->abort_flag)
break; break;
if (siw->device_scan_queued.exchange(false)) { if (siw->device_scan_queued) {
siw->device_scan_queued = false;
soundio_os_mutex_unlock(siw->scan_devices_mutex);
err = refresh_devices(si); err = refresh_devices(si);
if (err) { if (err) {
shutdown_backend(si, err); shutdown_backend(si, err);
return; return;
} }
soundio_os_mutex_lock(siw->scan_devices_mutex);
continue;
} }
soundio_os_cond_wait(siw->scan_devices_cond, nullptr); soundio_os_cond_wait(siw->scan_devices_cond, siw->scan_devices_mutex);
} }
soundio_os_mutex_unlock(siw->scan_devices_mutex);
IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(siw->device_enumerator, &siw->device_events); IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(siw->device_enumerator, &siw->device_events);
IMMDeviceEnumerator_Release(siw->device_enumerator); IMMDeviceEnumerator_Release(siw->device_enumerator);
@ -1019,8 +1025,10 @@ static void wakeup_wasapi(struct SoundIoPrivate *si) {
static void force_device_scan_wasapi(struct SoundIoPrivate *si) { static void force_device_scan_wasapi(struct SoundIoPrivate *si) {
SoundIoWasapi *siw = &si->backend_data.wasapi; SoundIoWasapi *siw = &si->backend_data.wasapi;
siw->device_scan_queued.store(true); soundio_os_mutex_lock(siw->scan_devices_mutex);
soundio_os_cond_signal(siw->scan_devices_cond, nullptr); siw->device_scan_queued = true;
soundio_os_cond_signal(siw->scan_devices_cond, siw->scan_devices_mutex);
soundio_os_mutex_unlock(siw->scan_devices_mutex);
} }
static void outstream_thread_deinit(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { static void outstream_thread_deinit(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
@ -1917,8 +1925,10 @@ static void destroy_wasapi(struct SoundIoPrivate *si) {
SoundIoWasapi *siw = &si->backend_data.wasapi; SoundIoWasapi *siw = &si->backend_data.wasapi;
if (siw->thread) { if (siw->thread) {
siw->abort_flag.clear(); soundio_os_mutex_lock(siw->scan_devices_mutex);
soundio_os_cond_signal(siw->scan_devices_cond, nullptr); siw->abort_flag = true;
soundio_os_cond_signal(siw->scan_devices_cond, siw->scan_devices_mutex);
soundio_os_mutex_unlock(siw->scan_devices_mutex);
soundio_os_thread_destroy(siw->thread); soundio_os_thread_destroy(siw->thread);
} }
@ -1928,6 +1938,9 @@ static void destroy_wasapi(struct SoundIoPrivate *si) {
if (siw->scan_devices_cond) if (siw->scan_devices_cond)
soundio_os_cond_destroy(siw->scan_devices_cond); soundio_os_cond_destroy(siw->scan_devices_cond);
if (siw->scan_devices_mutex)
soundio_os_mutex_destroy(siw->scan_devices_mutex);
if (siw->mutex) if (siw->mutex)
soundio_os_mutex_destroy(siw->mutex); soundio_os_mutex_destroy(siw->mutex);
@ -2013,8 +2026,7 @@ int soundio_wasapi_init(SoundIoPrivate *si) {
SoundIoWasapi *siw = &si->backend_data.wasapi; SoundIoWasapi *siw = &si->backend_data.wasapi;
int err; int err;
siw->device_scan_queued.store(true); siw->device_scan_queued = true;
siw->abort_flag.test_and_set();
siw->mutex = soundio_os_mutex_create(); siw->mutex = soundio_os_mutex_create();
if (!siw->mutex) { if (!siw->mutex) {
@ -2022,6 +2034,12 @@ int soundio_wasapi_init(SoundIoPrivate *si) {
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
siw->scan_devices_mutex = soundio_os_mutex_create();
if (!siw->scan_devices_mutex) {
destroy_wasapi(si);
return SoundIoErrorNoMem;
}
siw->cond = soundio_os_cond_create(); siw->cond = soundio_os_cond_create();
if (!siw->cond) { if (!siw->cond) {
destroy_wasapi(si); destroy_wasapi(si);

View file

@ -36,12 +36,13 @@ struct SoundIoWasapi {
SoundIoOsMutex *mutex; SoundIoOsMutex *mutex;
SoundIoOsCond *cond; SoundIoOsCond *cond;
SoundIoOsCond *scan_devices_cond; SoundIoOsCond *scan_devices_cond;
SoundIoOsMutex *scan_devices_mutex;
struct SoundIoOsThread *thread; struct SoundIoOsThread *thread;
atomic_flag abort_flag; bool abort_flag;
// this one is ready to be read with flush_events. protected by mutex // this one is ready to be read with flush_events. protected by mutex
struct SoundIoDevicesInfo *ready_devices_info; struct SoundIoDevicesInfo *ready_devices_info;
bool have_devices_flag; bool have_devices_flag;
atomic_bool device_scan_queued; bool device_scan_queued;
int shutdown_err; int shutdown_err;
bool emitted_shutdown_cb; bool emitted_shutdown_cb;