dummy: fix deadlock when pause called from write_callback

This commit is contained in:
Andrew Kelley 2015-10-06 19:36:57 -07:00
parent a3c4f85489
commit 277bb3106b
2 changed files with 40 additions and 40 deletions

View file

@ -44,6 +44,12 @@ static void playback_thread_run(void *arg) {
continue;
}
if (osd->pause_requested.load()) {
start_time = now;
frames_consumed = 0;
continue;
}
int fill_bytes = soundio_ring_buffer_fill_count(&osd->ring_buffer);
int fill_frames = fill_bytes / outstream->bytes_per_frame;
int free_bytes = soundio_ring_buffer_capacity(&osd->ring_buffer) - fill_bytes;
@ -86,6 +92,12 @@ static void capture_thread_run(void *arg) {
double relative_time = next_period - now;
soundio_os_cond_timed_wait(isd->cond, nullptr, relative_time);
if (isd->pause_requested.load()) {
start_time = now;
frames_consumed = 0;
continue;
}
int fill_bytes = soundio_ring_buffer_fill_count(&isd->ring_buffer);
int free_bytes = soundio_ring_buffer_capacity(&isd->ring_buffer) - fill_bytes;
int fill_frames = fill_bytes / instream->bytes_per_frame;
@ -166,6 +178,7 @@ static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
SoundIoDevice *device = outstream->device;
osd->clear_buffer_flag.test_and_set();
osd->pause_requested.store(false);
if (outstream->software_latency == 0.0)
outstream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max);
@ -193,30 +206,22 @@ static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
static int outstream_pause_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
SoundIo *soundio = &si->pub;
if (pause) {
if (osd->thread) {
osd->abort_flag.clear();
soundio_os_cond_signal(osd->cond, nullptr);
soundio_os_thread_destroy(osd->thread);
osd->thread = nullptr;
}
} else {
if (!osd->thread) {
osd->abort_flag.test_and_set();
int err;
if ((err = soundio_os_thread_create(playback_thread_run, os,
soundio->emit_rtprio_warning, &osd->thread)))
{
return err;
}
}
}
osd->pause_requested.store(pause);
return 0;
}
static int outstream_start_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
return outstream_pause_dummy(si, os, false);
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
SoundIo *soundio = &si->pub;
assert(!osd->thread);
osd->abort_flag.test_and_set();
int err;
if ((err = soundio_os_thread_create(playback_thread_run, os,
soundio->emit_rtprio_warning, &osd->thread)))
{
return err;
}
return 0;
}
static int outstream_begin_write_dummy(SoundIoPrivate *si,
@ -284,6 +289,7 @@ static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
SoundIoInStream *instream = &is->pub;
SoundIoDevice *device = instream->device;
isd->pause_requested.store(false);
if (instream->software_latency == 0.0)
instream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max);
@ -313,30 +319,22 @@ static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
static int instream_pause_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is, bool pause) {
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
SoundIo *soundio = &si->pub;
if (pause) {
if (isd->thread) {
isd->abort_flag.clear();
soundio_os_cond_signal(isd->cond, nullptr);
soundio_os_thread_destroy(isd->thread);
isd->thread = nullptr;
}
} else {
if (!isd->thread) {
isd->abort_flag.test_and_set();
int err;
if ((err = soundio_os_thread_create(capture_thread_run, is,
soundio->emit_rtprio_warning, &isd->thread)))
{
return err;
}
}
}
isd->pause_requested.store(pause);
return 0;
}
static int instream_start_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
return instream_pause_dummy(si, is, false);
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
SoundIo *soundio = &si->pub;
assert(!isd->thread);
isd->abort_flag.test_and_set();
int err;
if ((err = soundio_os_thread_create(capture_thread_run, is,
soundio->emit_rtprio_warning, &isd->thread)))
{
return err;
}
return 0;
}
static int instream_begin_read_dummy(SoundIoPrivate *si,

View file

@ -34,6 +34,7 @@ struct SoundIoOutStreamDummy {
struct SoundIoRingBuffer ring_buffer;
double playback_start_time;
atomic_flag clear_buffer_flag;
atomic_bool pause_requested;
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
};
@ -46,6 +47,7 @@ struct SoundIoInStreamDummy {
int read_frame_count;
int buffer_frame_count;
struct SoundIoRingBuffer ring_buffer;
atomic_bool pause_requested;
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
};