quartz: Use a condition variable to wake up the system clock advise thread.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6c0ddfee9d
commit
4df1a5831c
|
@ -42,10 +42,11 @@ struct system_clock
|
||||||
IUnknown *outer_unk;
|
IUnknown *outer_unk;
|
||||||
LONG refcount;
|
LONG refcount;
|
||||||
|
|
||||||
BOOL thread_created;
|
BOOL thread_created, thread_stopped;
|
||||||
HANDLE thread, notify_event, stop_event;
|
HANDLE thread;
|
||||||
REFERENCE_TIME last_time;
|
REFERENCE_TIME last_time;
|
||||||
CRITICAL_SECTION cs;
|
CRITICAL_SECTION cs;
|
||||||
|
CONDITION_VARIABLE cv;
|
||||||
|
|
||||||
struct list sinks;
|
struct list sinks;
|
||||||
};
|
};
|
||||||
|
@ -96,11 +97,12 @@ static ULONG WINAPI system_clock_inner_Release(IUnknown *iface)
|
||||||
{
|
{
|
||||||
if (clock->thread)
|
if (clock->thread)
|
||||||
{
|
{
|
||||||
SetEvent(clock->stop_event);
|
EnterCriticalSection(&clock->cs);
|
||||||
|
clock->thread_stopped = TRUE;
|
||||||
|
LeaveCriticalSection(&clock->cs);
|
||||||
|
WakeConditionVariable(&clock->cv);
|
||||||
WaitForSingleObject(clock->thread, INFINITE);
|
WaitForSingleObject(clock->thread, INFINITE);
|
||||||
CloseHandle(clock->thread);
|
CloseHandle(clock->thread);
|
||||||
CloseHandle(clock->notify_event);
|
|
||||||
CloseHandle(clock->stop_event);
|
|
||||||
}
|
}
|
||||||
clock->cs.DebugInfo->Spare[0] = 0;
|
clock->cs.DebugInfo->Spare[0] = 0;
|
||||||
DeleteCriticalSection(&clock->cs);
|
DeleteCriticalSection(&clock->cs);
|
||||||
|
@ -128,7 +130,6 @@ static DWORD WINAPI SystemClockAdviseThread(void *param)
|
||||||
struct system_clock *clock = param;
|
struct system_clock *clock = param;
|
||||||
struct advise_sink *sink, *cursor;
|
struct advise_sink *sink, *cursor;
|
||||||
REFERENCE_TIME current_time;
|
REFERENCE_TIME current_time;
|
||||||
HANDLE handles[2] = {clock->stop_event, clock->notify_event};
|
|
||||||
|
|
||||||
TRACE("Starting advise thread for clock %p.\n", clock);
|
TRACE("Starting advise thread for clock %p.\n", clock);
|
||||||
|
|
||||||
|
@ -162,10 +163,13 @@ static DWORD WINAPI SystemClockAdviseThread(void *param)
|
||||||
timeout = min(timeout, (sink->due_time - current_time) / 10000);
|
timeout = min(timeout, (sink->due_time - current_time) / 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&clock->cs);
|
SleepConditionVariableCS(&clock->cv, &clock->cs, timeout);
|
||||||
|
if (clock->thread_stopped)
|
||||||
if (WaitForMultipleObjects(2, handles, FALSE, timeout) == 0)
|
{
|
||||||
|
LeaveCriticalSection(&clock->cs);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&clock->cs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,11 +198,9 @@ static HRESULT add_sink(struct system_clock *clock, DWORD_PTR handle,
|
||||||
|
|
||||||
if (!InterlockedCompareExchange(&clock->thread_created, TRUE, FALSE))
|
if (!InterlockedCompareExchange(&clock->thread_created, TRUE, FALSE))
|
||||||
{
|
{
|
||||||
clock->notify_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
|
||||||
clock->stop_event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
|
||||||
clock->thread = CreateThread(NULL, 0, SystemClockAdviseThread, clock, 0, NULL);
|
clock->thread = CreateThread(NULL, 0, SystemClockAdviseThread, clock, 0, NULL);
|
||||||
}
|
}
|
||||||
SetEvent(clock->notify_event);
|
WakeConditionVariable(&clock->cv);
|
||||||
|
|
||||||
*cookie = sink->cookie;
|
*cookie = sink->cookie;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
Loading…
Reference in New Issue