Commit 9c531232 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

winegstreamer: Protect the "streaming" member of struct parser with a separate lock.

The code previously relied on inherent atomicity of atomic types, but atomicity doesn't imply the right memory ordering. Be explicit about the threading model we want. Signed-off-by: 's avatarZebediah Figura <zfigura@codeweavers.com>
parent 794763bb
...@@ -54,6 +54,15 @@ struct parser ...@@ -54,6 +54,15 @@ struct parser
struct wg_parser *wg_parser; struct wg_parser *wg_parser;
/* This protects the "streaming" field, accessed by both the application
* and streaming threads.
* We cannot use the filter lock for this, since that is held while waiting
* for the streaming thread, and hence the streaming thread cannot take the
* filter lock.
* This lock must not be acquired before acquiring the filter lock or
* flushing_cs. */
CRITICAL_SECTION streaming_cs;
/* FIXME: It would be nice to avoid duplicating these with strmbase. /* FIXME: It would be nice to avoid duplicating these with strmbase.
* However, synchronization is tricky; we need access to be protected by a * However, synchronization is tricky; we need access to be protected by a
* separate lock. */ * separate lock. */
...@@ -972,10 +981,18 @@ static DWORD CALLBACK stream_thread(void *arg) ...@@ -972,10 +981,18 @@ static DWORD CALLBACK stream_thread(void *arg)
TRACE("Starting streaming thread for pin %p.\n", pin); TRACE("Starting streaming thread for pin %p.\n", pin);
while (filter->streaming) for (;;)
{ {
struct wg_parser_buffer buffer; struct wg_parser_buffer buffer;
EnterCriticalSection(&filter->streaming_cs);
if (!filter->streaming)
{
LeaveCriticalSection(&filter->streaming_cs);
break;
}
LeaveCriticalSection(&filter->streaming_cs);
EnterCriticalSection(&pin->flushing_cs); EnterCriticalSection(&pin->flushing_cs);
if (pin->eos) if (pin->eos)
...@@ -1095,6 +1112,9 @@ static void parser_destroy(struct strmbase_filter *iface) ...@@ -1095,6 +1112,9 @@ static void parser_destroy(struct strmbase_filter *iface)
wg_parser_destroy(filter->wg_parser); wg_parser_destroy(filter->wg_parser);
filter->streaming_cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&filter->streaming_cs);
strmbase_sink_cleanup(&filter->sink); strmbase_sink_cleanup(&filter->sink);
strmbase_filter_cleanup(&filter->filter); strmbase_filter_cleanup(&filter->filter);
free(filter); free(filter);
...@@ -1167,7 +1187,9 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface) ...@@ -1167,7 +1187,9 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface)
if (!filter->sink_connected) if (!filter->sink_connected)
return S_OK; return S_OK;
EnterCriticalSection(&filter->streaming_cs);
filter->streaming = false; filter->streaming = false;
LeaveCriticalSection(&filter->streaming_cs);
for (i = 0; i < filter->source_count; ++i) for (i = 0; i < filter->source_count; ++i)
{ {
...@@ -1359,6 +1381,9 @@ static HRESULT parser_create(enum wg_parser_type type, struct parser **parser) ...@@ -1359,6 +1381,9 @@ static HRESULT parser_create(enum wg_parser_type type, struct parser **parser)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
InitializeCriticalSection(&object->streaming_cs);
object->streaming_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": parser.streaming_cs");
*parser = object; *parser = object;
return S_OK; return S_OK;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment