diff options
author | Chris Robinson <[email protected]> | 2017-01-10 03:02:26 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-01-10 03:02:26 -0800 |
commit | e20f0ae5a3c68767a7e08df96fbfa707f36ea6db (patch) | |
tree | efac7f9b2ec90d7fdff00ca2b64f1c80b1e90f05 | |
parent | 987b6e069bcb9947bf2739aca33d890ebad5bebc (diff) |
Hold Pulse's mainloop lock while calling capture functions
Since commit c837484015e, the backend's lock is no longer implicitly held when
calling capture functions. A separate mutex is used to ensure serial access,
and its up to the backend to protect against races and reentrancy with the
audio API.
-rw-r--r-- | Alc/backends/pulseaudio.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index f46386e4..fa07da3e 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -1558,17 +1558,20 @@ static void ALCpulseCapture_close(ALCpulseCapture *self) static ALCboolean ALCpulseCapture_start(ALCpulseCapture *self) { pa_operation *o; + pa_threaded_mainloop_lock(self->loop); o = pa_stream_cork(self->stream, 0, stream_success_callback, self->loop); wait_for_operation(o, self->loop); - + pa_threaded_mainloop_unlock(self->loop); return ALC_TRUE; } static void ALCpulseCapture_stop(ALCpulseCapture *self) { pa_operation *o; + pa_threaded_mainloop_lock(self->loop); o = pa_stream_cork(self->stream, 1, stream_success_callback, self->loop); wait_for_operation(o, self->loop); + pa_threaded_mainloop_unlock(self->loop); } static ALCenum ALCpulseCapture_captureSamples(ALCpulseCapture *self, ALCvoid *buffer, ALCuint samples) @@ -1579,6 +1582,7 @@ static ALCenum ALCpulseCapture_captureSamples(ALCpulseCapture *self, ALCvoid *bu /* Capture is done in fragment-sized chunks, so we loop until we get all * that's available */ self->last_readable -= todo; + pa_threaded_mainloop_lock(self->loop); while(todo > 0) { size_t rem = todo; @@ -1618,6 +1622,7 @@ static ALCenum ALCpulseCapture_captureSamples(ALCpulseCapture *self, ALCvoid *bu self->cap_len = 0; } } + pa_threaded_mainloop_unlock(self->loop); if(todo > 0) memset(buffer, ((device->FmtType==DevFmtUByte) ? 0x80 : 0), todo); @@ -1631,7 +1636,9 @@ static ALCuint ALCpulseCapture_availableSamples(ALCpulseCapture *self) if(device->Connected) { - ssize_t got = pa_stream_readable_size(self->stream); + ssize_t got; + pa_threaded_mainloop_lock(self->loop); + got = pa_stream_readable_size(self->stream); if(got < 0) { ERR("pa_stream_readable_size() failed: %s\n", pa_strerror(got)); @@ -1639,6 +1646,7 @@ static ALCuint ALCpulseCapture_availableSamples(ALCpulseCapture *self) } else if((size_t)got > self->cap_len) readable += got - self->cap_len; + pa_threaded_mainloop_unlock(self->loop); } if(self->last_readable < readable) |