[PATCH 2/4] quartz/systemclock: Store all the sinks in a single list.

Zebediah Figura z.figura12 at gmail.com
Sat Mar 16 09:11:48 CDT 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/quartz/systemclock.c | 116 +++++++++++++-------------------------
 1 file changed, 39 insertions(+), 77 deletions(-)

diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c
index f41cdbe534..f22c781a3b 100644
--- a/dlls/quartz/systemclock.c
+++ b/dlls/quartz/systemclock.c
@@ -45,8 +45,7 @@ typedef struct SystemClockImpl {
     REFERENCE_TIME last_time;
     CRITICAL_SECTION cs;
 
-    /* These lists are ordered by expiration time (soonest first). */
-    struct list single_sinks, periodic_sinks;
+    struct list sinks;
 } SystemClockImpl;
 
 static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface)
@@ -54,73 +53,48 @@ static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface)
     return CONTAINING_RECORD(iface, SystemClockImpl, IReferenceClock_iface);
 }
 
-static void insert_advise_sink(struct advise_sink *sink, struct list *queue)
+static DWORD WINAPI SystemClockAdviseThread(void *param)
 {
-    REFERENCE_TIME due_time = sink->due_time + sink->period;
-    struct advise_sink *cursor;
+    SystemClockImpl *clock = param;
+    struct advise_sink *sink, *cursor;
+    REFERENCE_TIME current_time;
+    DWORD timeout = INFINITE;
+    HANDLE handles[2] = {clock->stop_event, clock->notify_event};
 
-    LIST_FOR_EACH_ENTRY(cursor, queue, struct advise_sink, entry)
-    {
-        if (cursor->due_time + cursor->period > due_time)
-        {
-            list_add_before(&cursor->entry, &sink->entry);
-            return;
-        }
-    }
-
-    list_add_tail(queue, &sink->entry);
-}
-
-static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) {
-  SystemClockImpl* This = lpParam;
-  struct advise_sink *sink, *cursor;
-  struct list *entry;
-  DWORD timeOut = INFINITE;
-  REFERENCE_TIME curTime;
-  HANDLE handles[2] = {This->stop_event, This->notify_event};
-
-  TRACE("(%p): Main Loop\n", This);
+    TRACE("Starting advise thread for clock %p.\n", clock);
 
-  while (TRUE) {
-    EnterCriticalSection(&This->cs);
-
-    curTime = GetTickCount64() * 10000;
-
-    /** First SingleShots Advice: sorted list */
-    LIST_FOR_EACH_ENTRY_SAFE(sink, cursor, &This->single_sinks, struct advise_sink, entry)
+    for (;;)
     {
-      if (sink->due_time + sink->period > curTime)
-        break;
+        EnterCriticalSection(&clock->cs);
 
-      SetEvent(sink->handle);
-      list_remove(&sink->entry);
-      heap_free(sink);
-    }
+        current_time = GetTickCount64() * 10000;
 
-    if ((entry = list_head(&This->single_sinks)))
-    {
-      sink = LIST_ENTRY(entry, struct advise_sink, entry);
-      timeOut = (sink->due_time + sink->period - curTime) / 10000;
-    }
-    else timeOut = INFINITE;
-
-    /** Now Periodics Advice: semi sorted list (sort cannot be used) */
-    LIST_FOR_EACH_ENTRY(sink, &This->periodic_sinks, struct advise_sink, entry)
-    {
-      if (sink->due_time <= curTime)
-      {
-        DWORD periods = ((curTime - sink->due_time) / sink->period) + 1;
-        ReleaseSemaphore(sink->handle, periods, NULL);
-        sink->due_time += periods * sink->period;
-      }
-      timeOut = min(timeOut, (sink->due_time - curTime) / 10000);
-    }
+        LIST_FOR_EACH_ENTRY_SAFE(sink, cursor, &clock->sinks, struct advise_sink, entry)
+        {
+            if (sink->due_time <= current_time)
+            {
+                if (sink->period)
+                {
+                    DWORD periods = ((current_time - sink->due_time) / sink->period) + 1;
+                    ReleaseSemaphore(sink->handle, periods, NULL);
+                    sink->due_time += periods * sink->period;
+                }
+                else
+                {
+                    SetEvent(sink->handle);
+                    list_remove(&sink->entry);
+                    heap_free(sink);
+                }
+            }
+
+            timeout = min(timeout, (sink->due_time - current_time) / 10000);
+        }
 
-    LeaveCriticalSection(&This->cs);
+        LeaveCriticalSection(&clock->cs);
 
-    if (WaitForMultipleObjects(2, handles, FALSE, timeOut) == 0)
-        return 0;
-  }
+        if (WaitForMultipleObjects(2, handles, FALSE, timeout) == 0)
+            return 0;
+    }
 }
 
 static void notify_thread(SystemClockImpl *clock)
@@ -234,7 +208,7 @@ static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock *iface,
     sink->cookie = InterlockedIncrement(&cookie_counter);
 
     EnterCriticalSection(&clock->cs);
-    insert_advise_sink(sink, &clock->single_sinks);
+    list_add_tail(&clock->sinks, &sink->entry);
     LeaveCriticalSection(&clock->cs);
 
     notify_thread(clock);
@@ -270,7 +244,7 @@ static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface,
     sink->cookie = InterlockedIncrement(&cookie_counter);
 
     EnterCriticalSection(&clock->cs);
-    insert_advise_sink(sink, &clock->periodic_sinks);
+    list_add_tail(&clock->sinks, &sink->entry);
     LeaveCriticalSection(&clock->cs);
 
     notify_thread(clock);
@@ -288,18 +262,7 @@ static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR
 
     EnterCriticalSection(&clock->cs);
 
-    LIST_FOR_EACH_ENTRY(sink, &clock->single_sinks, struct advise_sink, entry)
-    {
-        if (sink->cookie == cookie)
-        {
-            list_remove(&sink->entry);
-            heap_free(sink);
-            LeaveCriticalSection(&clock->cs);
-            return S_OK;
-        }
-    }
-
-    LIST_FOR_EACH_ENTRY(sink, &clock->periodic_sinks, struct advise_sink, entry)
+    LIST_FOR_EACH_ENTRY(sink, &clock->sinks, struct advise_sink, entry)
     {
         if (sink->cookie == cookie)
         {
@@ -339,8 +302,7 @@ HRESULT QUARTZ_CreateSystemClock(IUnknown *outer, void **out)
     }
 
     object->IReferenceClock_iface.lpVtbl = &SystemClock_Vtbl;
-    list_init(&object->single_sinks);
-    list_init(&object->periodic_sinks);
+    list_init(&object->sinks);
     InitializeCriticalSection(&object->cs);
     object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SystemClockImpl.cs");
 
-- 
2.20.1




More information about the wine-devel mailing list