From: "Erich E. Hoover" Subject: [PATCH 1/6] strmbase: Fix race condition on InputPin_BeginFlush between csRenderLock and filter.csFilter. Message-Id: Date: Wed, 30 Jul 2014 19:46:39 -0600 Finally took the time to track down bug #31566 (Fallout 3/NV radio problems) after the big move to strmbase. This patch changes the locking order between csRenderLock and filter.csFilter to keep a race condition from occurring when BaseRendererImpl_Receive and BaseRenderer_InputPin_BeginFlush are called. After carefully combing the strmbase code it is pretty clear that csRenderLock is the "bigger" lock (when compared to filter.csFilter), but the case described above triggers the particular instantiation of the problem in F3/FNV: == Thread 1== BaseRendererImpl_Receive -> EnterCriticalSection(csRenderLock); -> ... -> QualityControlRender_BeginRender -> ReferenceClock_GetTime -> EnterCriticalSection(filter.csFilter); -> ... -> LeaveCriticalSection(filter.csFilter); -> ... -> LeaveCriticalSection(csRenderLock); == Thread 2== BaseRenderer_InputPin_BeginFlush -> EnterCriticalSection(filter.csFilter); -> EnterCriticalSection(csRenderLock); -> ... -> LeaveCriticalSection(filter.csFilter); -> LeaveCriticalSection(csRenderLock); As you can see, the lock order here means that if BaseRenderer_InputPin_BeginFlush occurs while BaseRendererImpl_Receive is being processed that it will lock the "inner" lock (filter.csFilter) and then both locks will be set, causing a deadlock. Patches 2-5 standardize the rest of the locking in strmbase/quartz to match this behavior (where it doesn't already). From d05f0c10477011454b3ec227db34aca34197d829 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 17 Jul 2014 10:28:42 -0600 Subject: strmbase: Fix race condition on InputPin_BeginFlush between csRenderLock and filter.csFilter. --- dlls/strmbase/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 766e467..3acca0f 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -130,8 +130,8 @@ static HRESULT WINAPI BaseRenderer_InputPin_BeginFlush(IPin * iface) TRACE("(%p/%p)->()\n", This, iface); - EnterCriticalSection(&pFilter->filter.csFilter); EnterCriticalSection(&pFilter->csRenderLock); + EnterCriticalSection(&pFilter->filter.csFilter); EnterCriticalSection(This->pin.pCritSec); hr = BaseInputPinImpl_BeginFlush(iface); if (SUCCEEDED(hr)) -- 1.7.9.5