Commit 86cbfa4b authored by Anton Baskanov's avatar Anton Baskanov Committed by Alexandre Julliard

quartz: Use a separate critical section for events.

parent 4fb34831
...@@ -104,6 +104,11 @@ struct filter_graph ...@@ -104,6 +104,11 @@ struct filter_graph
IReferenceClock *refClock; IReferenceClock *refClock;
IBaseFilter *refClockProvider; IBaseFilter *refClockProvider;
/* We may indirectly wait for streaming threads while holding graph->cs in
* IMediaFilter::Stop() or IMediaSeeking::SetPositions(). Since streaming
* threads call IMediaEventSink::Notify() to queue EC_COMPLETE, we must
* use a separate lock to avoid them deadlocking on graph->cs. */
CRITICAL_SECTION event_cs;
struct list media_events; struct list media_events;
HANDLE media_event_handle; HANDLE media_event_handle;
HWND media_event_window; HWND media_event_window;
...@@ -116,6 +121,8 @@ struct filter_graph ...@@ -116,6 +121,8 @@ struct filter_graph
int HandleEcComplete; int HandleEcComplete;
int HandleEcRepaint; int HandleEcRepaint;
int HandleEcClockChanged; int HandleEcClockChanged;
unsigned int got_ec_complete : 1;
unsigned int media_events_disabled : 1;
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES]; ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
...@@ -135,8 +142,6 @@ struct filter_graph ...@@ -135,8 +142,6 @@ struct filter_graph
LONGLONG current_pos; LONGLONG current_pos;
unsigned int needs_async_run : 1; unsigned int needs_async_run : 1;
unsigned int got_ec_complete : 1;
unsigned int media_events_disabled : 1;
}; };
struct enum_filters struct enum_filters
...@@ -467,6 +472,7 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface) ...@@ -467,6 +472,7 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface)
CloseHandle(This->message_thread); CloseHandle(This->message_thread);
CloseHandle(This->message_thread_ret); CloseHandle(This->message_thread_ret);
} }
DeleteCriticalSection(&This->event_cs);
DeleteCriticalSection(&This->cs); DeleteCriticalSection(&This->cs);
free(This); free(This);
...@@ -1695,8 +1701,10 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta ...@@ -1695,8 +1701,10 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta
struct filter *filter; struct filter *filter;
HRESULT hr = S_OK; HRESULT hr = S_OK;
EnterCriticalSection(&graph->event_cs);
graph->EcCompleteCount = 0; graph->EcCompleteCount = 0;
update_render_count(graph); update_render_count(graph);
LeaveCriticalSection(&graph->event_cs);
LIST_FOR_EACH_ENTRY_SAFE(event, next, &graph->media_events, struct media_event, entry) LIST_FOR_EACH_ENTRY_SAFE(event, next, &graph->media_events, struct media_event, entry)
{ {
...@@ -1813,7 +1821,10 @@ static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) ...@@ -1813,7 +1821,10 @@ static HRESULT WINAPI MediaControl_Run(IMediaControl *iface)
} }
sort_filters(graph); sort_filters(graph);
EnterCriticalSection(&graph->event_cs);
update_render_count(graph); update_render_count(graph);
LeaveCriticalSection(&graph->event_cs);
if (graph->state == State_Stopped) if (graph->state == State_Stopped)
{ {
...@@ -4752,12 +4763,12 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *code, ...@@ -4752,12 +4763,12 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *code,
if (WaitForSingleObject(graph->media_event_handle, timeout)) if (WaitForSingleObject(graph->media_event_handle, timeout))
return E_ABORT; return E_ABORT;
EnterCriticalSection(&graph->cs); EnterCriticalSection(&graph->event_cs);
if (!(entry = list_head(&graph->media_events))) if (!(entry = list_head(&graph->media_events)))
{ {
ResetEvent(graph->media_event_handle); ResetEvent(graph->media_event_handle);
LeaveCriticalSection(&graph->cs); LeaveCriticalSection(&graph->event_cs);
return E_ABORT; return E_ABORT;
} }
event = LIST_ENTRY(entry, struct media_event, entry); event = LIST_ENTRY(entry, struct media_event, entry);
...@@ -4767,7 +4778,7 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *code, ...@@ -4767,7 +4778,7 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *code,
*param2 = event->param2; *param2 = event->param2;
free(event); free(event);
LeaveCriticalSection(&graph->cs); LeaveCriticalSection(&graph->event_cs);
return S_OK; return S_OK;
} }
...@@ -5015,7 +5026,10 @@ static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) ...@@ -5015,7 +5026,10 @@ static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface)
} }
sort_filters(graph); sort_filters(graph);
EnterCriticalSection(&graph->event_cs);
update_render_count(graph); update_render_count(graph);
LeaveCriticalSection(&graph->event_cs);
if (graph->defaultclock && !graph->refClock) if (graph->defaultclock && !graph->refClock)
IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface); IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface);
...@@ -5261,7 +5275,7 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG code, ...@@ -5261,7 +5275,7 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG code,
TRACE("graph %p, code %#x, param1 %#Ix, param2 %#Ix.\n", graph, code, param1, param2); 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) if (code == EC_COMPLETE && graph->HandleEcComplete)
{ {
...@@ -5285,7 +5299,7 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG code, ...@@ -5285,7 +5299,7 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG code,
queue_media_event(graph, code, param1, param2); queue_media_event(graph, code, param1, param2);
} }
LeaveCriticalSection(&graph->cs); LeaveCriticalSection(&graph->event_cs);
return S_OK; return S_OK;
} }
...@@ -5591,6 +5605,8 @@ static HRESULT filter_graph_common_create(IUnknown *outer, IUnknown **out, BOOL ...@@ -5591,6 +5605,8 @@ static HRESULT filter_graph_common_create(IUnknown *outer, IUnknown **out, BOOL
InitializeCriticalSection(&object->cs); InitializeCriticalSection(&object->cs);
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": filter_graph.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; object->defaultclock = TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment