From: Zhiyi Zhang zzhang@codeweavers.com
In clock_change_state() when a clock is running, a timer is removed from clock->timers. The same timer is then used to create an async result, which will eventually calls present_clock_timer_callback_Invoke() and release the same timer. This patch checks if the timer is still in clock->timers before releasing it. --- dlls/mf/clock.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/clock.c b/dlls/mf/clock.c index aef4366c6d9..e6be05d2794 100644 --- a/dlls/mf/clock.c +++ b/dlls/mf/clock.c @@ -1108,13 +1108,19 @@ static HRESULT WINAPI present_clock_timer_callback_Invoke(IMFAsyncCallback *ifac if (FAILED(hr = IMFAsyncResult_GetObject(result, &object))) return hr;
- timer = impl_clock_timer_from_IUnknown(object); - EnterCriticalSection(&clock->cs); - list_remove(&timer->entry); - IUnknown_Release(&timer->IUnknown_iface); + LIST_FOR_EACH_ENTRY(timer, &clock->timers, struct clock_timer, entry) + { + if (&timer->IUnknown_iface == object) + { + list_remove(&timer->entry); + IUnknown_Release(&timer->IUnknown_iface); + break; + } + } LeaveCriticalSection(&clock->cs);
+ timer = impl_clock_timer_from_IUnknown(object); IMFAsyncCallback_Invoke(timer->callback, timer->result);
IUnknown_Release(object);