On 4/6/21 1:04 PM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
This is required to avoid deadlocks, e.g. when MediaStreamFilter sends EC_COMPLETE while the graph is being stopped.
Can you please add a comment to this effect to the code?
dlls/quartz/filtergraph.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index a8c6cc3391c..1c8bdca99e7 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -104,6 +104,7 @@ struct filter_graph IReferenceClock *refClock; IBaseFilter *refClockProvider;
- CRITICAL_SECTION event_cs; struct list media_events; HANDLE media_event_handle; HWND media_event_window;
@@ -116,6 +117,8 @@ struct filter_graph int HandleEcComplete; int HandleEcRepaint; int HandleEcClockChanged;
unsigned int got_ec_complete : 1;
unsigned int media_events_disabled : 1;
CRITICAL_SECTION cs; ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
@@ -135,8 +138,6 @@ struct filter_graph LONGLONG current_pos;
unsigned int needs_async_run : 1;
unsigned int got_ec_complete : 1;
unsigned int media_events_disabled : 1; };
struct enum_filters
@@ -467,6 +468,7 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface) CloseHandle(This->message_thread); CloseHandle(This->message_thread_ret); }
DeleteCriticalSection(&This->cs); free(This);DeleteCriticalSection(&This->event_cs);
@@ -1695,8 +1697,10 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta struct filter *filter; HRESULT hr = S_OK;
EnterCriticalSection(&graph->event_cs); graph->EcCompleteCount = 0; update_render_count(graph);
LeaveCriticalSection(&graph->event_cs);
LIST_FOR_EACH_ENTRY_SAFE(event, next, &graph->media_events, struct media_event, entry) {
@@ -1813,7 +1817,10 @@ static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) }
sort_filters(graph);
EnterCriticalSection(&graph->event_cs); update_render_count(graph);
LeaveCriticalSection(&graph->event_cs);
if (graph->state == State_Stopped) {
@@ -4752,12 +4759,12 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *code, if (WaitForSingleObject(graph->media_event_handle, timeout)) return E_ABORT;
- EnterCriticalSection(&graph->cs);
EnterCriticalSection(&graph->event_cs);
if (!(entry = list_head(&graph->media_events))) { ResetEvent(graph->media_event_handle);
LeaveCriticalSection(&graph->cs);
LeaveCriticalSection(&graph->event_cs); return E_ABORT; } event = LIST_ENTRY(entry, struct media_event, entry);
@@ -4767,7 +4774,7 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *code, *param2 = event->param2; free(event);
- LeaveCriticalSection(&graph->cs);
- LeaveCriticalSection(&graph->event_cs); return S_OK; }
@@ -5015,7 +5022,10 @@ static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) }
sort_filters(graph);
EnterCriticalSection(&graph->event_cs); update_render_count(graph);
LeaveCriticalSection(&graph->event_cs);
if (graph->defaultclock && !graph->refClock) IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface);
@@ -5261,7 +5271,7 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG code,
TRACE("graph %p, code %#x, param1 %#Ix, param2 %#Ix.\n", graph, code, param1, param2);
- EnterCriticalSection(&graph->cs);
EnterCriticalSection(&graph->event_cs);
if (code == EC_COMPLETE && graph->HandleEcComplete) {
@@ -5285,7 +5295,7 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG code, queue_media_event(graph, code, param1, param2); }
- LeaveCriticalSection(&graph->cs);
- LeaveCriticalSection(&graph->event_cs); return S_OK; }
@@ -5591,6 +5601,8 @@ static HRESULT filter_graph_common_create(IUnknown *outer, IUnknown **out, BOOL
InitializeCriticalSection(&object->cs); object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": filter_graph.cs");
InitializeCriticalSection(&object->event_cs);
object->event_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": filter_graph.event_cs");
object->defaultclock = TRUE;