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: Zebediah Figura <zfigura@codeweavers.com>
This commit is contained in:
parent
794763bb60
commit
9c53123277
1 changed files with 26 additions and 1 deletions
|
@ -54,6 +54,15 @@ struct 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.
|
||||
* However, synchronization is tricky; we need access to be protected by a
|
||||
* separate lock. */
|
||||
|
@ -972,10 +981,18 @@ static DWORD CALLBACK stream_thread(void *arg)
|
|||
|
||||
TRACE("Starting streaming thread for pin %p.\n", pin);
|
||||
|
||||
while (filter->streaming)
|
||||
for (;;)
|
||||
{
|
||||
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);
|
||||
|
||||
if (pin->eos)
|
||||
|
@ -1095,6 +1112,9 @@ static void parser_destroy(struct strmbase_filter *iface)
|
|||
|
||||
wg_parser_destroy(filter->wg_parser);
|
||||
|
||||
filter->streaming_cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&filter->streaming_cs);
|
||||
|
||||
strmbase_sink_cleanup(&filter->sink);
|
||||
strmbase_filter_cleanup(&filter->filter);
|
||||
free(filter);
|
||||
|
@ -1167,7 +1187,9 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface)
|
|||
if (!filter->sink_connected)
|
||||
return S_OK;
|
||||
|
||||
EnterCriticalSection(&filter->streaming_cs);
|
||||
filter->streaming = false;
|
||||
LeaveCriticalSection(&filter->streaming_cs);
|
||||
|
||||
for (i = 0; i < filter->source_count; ++i)
|
||||
{
|
||||
|
@ -1359,6 +1381,9 @@ static HRESULT parser_create(enum wg_parser_type type, struct parser **parser)
|
|||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&object->streaming_cs);
|
||||
object->streaming_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": parser.streaming_cs");
|
||||
|
||||
*parser = object;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue