[PATCH 2/4] quartz: Use a condition variable to wake up the system clock advise thread.

Zebediah Figura zfigura at codeweavers.com
Mon Jul 19 22:25:25 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/quartz/systemclock.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c
index cbe5f395258..597373a4112 100644
--- a/dlls/quartz/systemclock.c
+++ b/dlls/quartz/systemclock.c
@@ -42,10 +42,11 @@ struct system_clock
     IUnknown *outer_unk;
     LONG refcount;
 
-    BOOL thread_created;
-    HANDLE thread, notify_event, stop_event;
+    BOOL thread_created, thread_stopped;
+    HANDLE thread;
     REFERENCE_TIME last_time;
     CRITICAL_SECTION cs;
+    CONDITION_VARIABLE cv;
 
     struct list sinks;
 };
@@ -96,11 +97,12 @@ static ULONG WINAPI system_clock_inner_Release(IUnknown *iface)
     {
         if (clock->thread)
         {
-            SetEvent(clock->stop_event);
+            EnterCriticalSection(&clock->cs);
+            clock->thread_stopped = TRUE;
+            LeaveCriticalSection(&clock->cs);
+            WakeConditionVariable(&clock->cv);
             WaitForSingleObject(clock->thread, INFINITE);
             CloseHandle(clock->thread);
-            CloseHandle(clock->notify_event);
-            CloseHandle(clock->stop_event);
         }
         clock->cs.DebugInfo->Spare[0] = 0;
         DeleteCriticalSection(&clock->cs);
@@ -128,7 +130,6 @@ static DWORD WINAPI SystemClockAdviseThread(void *param)
     struct system_clock *clock = param;
     struct advise_sink *sink, *cursor;
     REFERENCE_TIME current_time;
-    HANDLE handles[2] = {clock->stop_event, clock->notify_event};
 
     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);
         }
 
-        LeaveCriticalSection(&clock->cs);
-
-        if (WaitForMultipleObjects(2, handles, FALSE, timeout) == 0)
+        SleepConditionVariableCS(&clock->cv, &clock->cs, timeout);
+        if (clock->thread_stopped)
+        {
+            LeaveCriticalSection(&clock->cs);
             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))
     {
-        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);
     }
-    SetEvent(clock->notify_event);
+    WakeConditionVariable(&clock->cv);
 
     *cookie = sink->cookie;
     return S_OK;
-- 
2.32.0




More information about the wine-devel mailing list