mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-05 07:15:34 -04:00
gst: pool: fix buffer release race condition
A call to `release_buffer()` may happen in a gstreamer thread concurrently
with the pipewire stream emitting the `remove_buffer` event in the thread
loop, which, in pipewiresink calls `gst_pipewire_pool_remove_buffer()`, which
in turn modifies the `GstPipeWirePoolData` object. Thus a data race occurs
when accessing its members, which can lead to `pw_stream_return_buffer()`
being called with a null pointer.
Fix that by locking the thread loop before checking the conditions.
Fixes: c0a6a7ea32 ("gst: handle flush event in pipewiresink")
This commit is contained in:
parent
64e0a9cbd9
commit
2770143f50
1 changed files with 5 additions and 6 deletions
|
|
@ -432,26 +432,25 @@ release_buffer (GstBufferPool * pool, GstBuffer *buffer)
|
||||||
GST_LOG_OBJECT (pool, "release buffer %p", buffer);
|
GST_LOG_OBJECT (pool, "release buffer %p", buffer);
|
||||||
|
|
||||||
GstPipeWirePoolData *data = gst_pipewire_pool_get_data(buffer);
|
GstPipeWirePoolData *data = gst_pipewire_pool_get_data(buffer);
|
||||||
|
GstPipeWirePool *p = GST_PIPEWIRE_POOL (pool);
|
||||||
|
g_autoptr (GstPipeWireStream) s = g_weak_ref_get (&p->stream);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (pool);
|
GST_OBJECT_LOCK (pool);
|
||||||
|
pw_thread_loop_lock (s->core->loop);
|
||||||
|
|
||||||
if (!data->queued && data->b != NULL)
|
if (!data->queued && data->b != NULL)
|
||||||
{
|
{
|
||||||
GstPipeWirePool *p = GST_PIPEWIRE_POOL (pool);
|
|
||||||
g_autoptr (GstPipeWireStream) s = g_weak_ref_get (&p->stream);
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
pw_thread_loop_lock (s->core->loop);
|
|
||||||
|
|
||||||
if ((res = pw_stream_return_buffer (s->pwstream, data->b)) < 0) {
|
if ((res = pw_stream_return_buffer (s->pwstream, data->b)) < 0) {
|
||||||
GST_ERROR_OBJECT (pool,"can't return buffer %p; gstbuffer : %p, %s",data->b, buffer, spa_strerror(res));
|
GST_ERROR_OBJECT (pool,"can't return buffer %p; gstbuffer : %p, %s",data->b, buffer, spa_strerror(res));
|
||||||
} else {
|
} else {
|
||||||
data->queued = TRUE;
|
data->queued = TRUE;
|
||||||
GST_DEBUG_OBJECT (pool, "returned buffer %p; gstbuffer:%p", data->b, buffer);
|
GST_DEBUG_OBJECT (pool, "returned buffer %p; gstbuffer:%p", data->b, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pw_thread_loop_unlock (s->core->loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pw_thread_loop_unlock (s->core->loop);
|
||||||
GST_OBJECT_UNLOCK (pool);
|
GST_OBJECT_UNLOCK (pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue