aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-01-10 03:02:26 -0800
committerChris Robinson <[email protected]>2017-01-10 03:02:26 -0800
commite20f0ae5a3c68767a7e08df96fbfa707f36ea6db (patch)
treeefac7f9b2ec90d7fdff00ca2b64f1c80b1e90f05
parent987b6e069bcb9947bf2739aca33d890ebad5bebc (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.c12
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)