From: Alfred Agrell floating@muncher.se
Latter is meaningless in this commit, but necessary in the next. --- dlls/winegstreamer/wm_reader.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 09f69bc6208..595baeea060 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -54,6 +54,7 @@ struct wm_reader LONG refcount;
CRITICAL_SECTION cs; + CRITICAL_SECTION init_cs; /* Protects wg_parser and read_thread_shutdown */ QWORD start_time; QWORD file_size;
@@ -601,15 +602,25 @@ static DWORD CALLBACK read_thread(void *arg)
TRACE("Starting read thread for reader %p.\n", reader);
- while (!reader->read_thread_shutdown) + while (true) { + wg_parser_t parser; LARGE_INTEGER large_offset; uint64_t offset; ULONG ret_size; uint32_t size; HRESULT hr;
- if (!wg_parser_get_next_read_offset(reader->wg_parser, &offset, &size)) + EnterCriticalSection(&reader->init_cs); + if (reader->read_thread_shutdown) + { + LeaveCriticalSection(&reader->init_cs); + break; + } + parser = reader->wg_parser; + LeaveCriticalSection(&reader->init_cs); + + if (!wg_parser_get_next_read_offset(parser, &offset, &size)) continue;
if (offset >= file_size) @@ -619,7 +630,7 @@ static DWORD CALLBACK read_thread(void *arg)
if (!size) { - wg_parser_push_data(reader->wg_parser, data, 0); + wg_parser_push_data(parser, data, 0); continue; }
@@ -638,7 +649,7 @@ static DWORD CALLBACK read_thread(void *arg) || !ReadFile(file, data, size, &ret_size, NULL)) { ERR("Failed to read %u bytes at offset %I64u, error %lu.\n", size, offset, GetLastError()); - wg_parser_push_data(reader->wg_parser, NULL, 0); + wg_parser_push_data(parser, NULL, 0); continue; } } @@ -649,14 +660,14 @@ static DWORD CALLBACK read_thread(void *arg) if (FAILED(hr)) { ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); - wg_parser_push_data(reader->wg_parser, NULL, 0); + wg_parser_push_data(parser, NULL, 0); continue; } }
if (ret_size != size) ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size); - wg_parser_push_data(reader->wg_parser, data, ret_size); + wg_parser_push_data(parser, data, ret_size); }
free(data); @@ -1450,6 +1461,7 @@ static HRESULT init_stream(struct wm_reader *reader)
reader->wg_parser = wg_parser; reader->read_thread_shutdown = false; + if (!(reader->read_thread = CreateThread(NULL, 0, read_thread, reader, 0, NULL))) { hr = E_OUTOFMEMORY; @@ -1517,14 +1529,18 @@ out_disconnect_parser: wg_parser_disconnect(reader->wg_parser);
out_shutdown_thread: + EnterCriticalSection(&reader->init_cs); reader->read_thread_shutdown = true; + LeaveCriticalSection(&reader->init_cs); WaitForSingleObject(reader->read_thread, INFINITE); CloseHandle(reader->read_thread); reader->read_thread = NULL;
out_destroy_parser: + EnterCriticalSection(&reader->init_cs); wg_parser_destroy(reader->wg_parser); reader->wg_parser = 0; + LeaveCriticalSection(&reader->init_cs);
return hr; } @@ -1728,6 +1744,8 @@ static ULONG WINAPI unknown_inner_Release(IUnknown *iface)
reader->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&reader->cs); + reader->init_cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&reader->init_cs);
free(reader); } @@ -1781,7 +1799,9 @@ static HRESULT WINAPI reader_Close(IWMSyncReader2 *iface)
wg_parser_disconnect(reader->wg_parser);
+ EnterCriticalSection(&reader->init_cs); reader->read_thread_shutdown = true; + LeaveCriticalSection(&reader->init_cs); WaitForSingleObject(reader->read_thread, INFINITE); CloseHandle(reader->read_thread); reader->read_thread = NULL; @@ -2557,6 +2577,8 @@ HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out)
InitializeCriticalSection(&object->cs); object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": reader.cs"); + InitializeCriticalSection(&object->init_cs); + object->init_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": reader.init_cs");
TRACE("Created reader %p.\n", object); *out = outer ? (void *)&object->IUnknown_inner : (void *)&object->IWMSyncReader2_iface;