This is just a draft to receive feedback, I'm not sure how could I test this behavior, right now the test I wrote works but there are times where it doesn't enter into the deadlock.
Also I'm not sure if leaving the critical section before waiting for the streaming thread is the correct way to solve the problem.
-- v2: evr: Leave critical section before waiting for streaming thread.
From: Santino Mazza smazza@codeweavers.com
Because the streaming thread enters the critical section when it receives an EVRM_PROCESS_INPUT message, it's possible to get into a deadlock when sending ENDSTREAMING before the streaming thread started processing the EVRM_PROCESS_INPUT message. --- dlls/evr/presenter.c | 3 +++ dlls/evr/tests/evr.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 06592f8766e..674bd298c33 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -747,8 +747,11 @@ static HRESULT video_presenter_end_streaming(struct video_presenter *presenter)
PostThreadMessageW(presenter->thread.tid, EVRM_STOP, 0, 0);
+ /* Make sure streaming thread is not blocked by critical section before waiting for it. */ + LeaveCriticalSection(&presenter->cs); WaitForSingleObject(presenter->thread.hthread, INFINITE); CloseHandle(presenter->thread.hthread); + EnterCriticalSection(&presenter->cs);
TRACE("Terminated streaming thread tid %#lx.\n", presenter->thread.tid);
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 8842a858b83..c810bf66286 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -3433,7 +3433,6 @@ static void test_presenter_orientation(const GUID *subtype) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - IDirect3DSurface9_Release(surface);
hr = IMFTransform_ProcessInput(mixer, 0, sample, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -3469,6 +3468,17 @@ static void test_presenter_orientation(const GUID *subtype) ok(diff <= 5, "Unexpected %lu%% diff\n", diff); CoTaskMemFree(data);
+ /* Test behaviour when sending ENDSTREAMING message while processing input. */ + hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IDirect3DSurface9_Release(surface); + + hr = IMFTransform_ProcessInput(mixer, 0, sample, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_PROCESSINPUTNOTIFY, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFSample_Release(sample); + hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_ENDSTREAMING, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);