[PATCH 5/5] quartz: Use a separate critical section for events.

Zebediah Figura (she/her) zfigura at codeweavers.com
Thu Apr 8 10:39:52 CDT 2021


On 4/6/21 1:04 PM, Anton Baskanov wrote:
> Signed-off-by: Anton Baskanov <baskanov at 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->event_cs);
>   	DeleteCriticalSection(&This->cs);
>           free(This);
>   
> @@ -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;
>   
> 



More information about the wine-devel mailing list