Use ConditionalWait::WaitUntil instead sleep_until 17/318017/9
authorEunki Hong <eunkiki.hong@samsung.com>
Mon, 23 Sep 2024 15:29:19 +0000 (00:29 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Thu, 10 Oct 2024 01:45:05 +0000 (01:45 +0000)
Since we cannot cancel SleepThread's sleeping
when std::this_thread::sleep_until,

Let we use std::conditional_wait's wait_until feature.

Since we already use ConditionalWait's wait + lock pair
to wait and release the SleepThread (at SleepUntil and Finalize)
we don't need to make additional mutex and conditional wait for it.

Change-Id: I7ee8a09bc4b9aa222efdf35f70da842917795365
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp

index ff9b7770fbe929b68ffecfabcd91a78ac9d99d9a..633a28d1bfef2e967f3fdc57cf7e2483b0abfd24 100644 (file)
@@ -509,9 +509,12 @@ void VectorAnimationThread::SleepThread::SleepUntil(std::chrono::time_point<std:
 
   if(DALI_LIKELY(!mDestroyThread))
   {
-    mSleepTimePoint = timeToSleepUntil;
-    mNeedToSleep    = true;
-    mConditionalWait.Notify(lock);
+    if(mSleepTimePoint != timeToSleepUntil) ///< Trigger only if new time point is changed.
+    {
+      mSleepTimePoint = timeToSleepUntil;
+      mNeedToSleep    = true;
+      mConditionalWait.Notify(lock);
+    }
   }
 }
 
@@ -537,42 +540,58 @@ void VectorAnimationThread::SleepThread::Run()
   {
     bool needToSleep = false;
 
-    std::chrono::time_point<std::chrono::steady_clock> sleepTimePoint;
-
     {
       ConditionalWait::ScopedLock lock(mConditionalWait);
-      Mutex::ScopedLock           sleepLock(mSleepRequestMutex);
 
-      if(DALI_LIKELY(!mDestroyThread))
+      ConditionalWait::TimePoint sleepTimePoint;
+
       {
-        needToSleep    = mNeedToSleep;
-        sleepTimePoint = mSleepTimePoint;
+        Mutex::ScopedLock sleepLock(mSleepRequestMutex);
 
-        mNeedToSleep = false;
+        if(DALI_LIKELY(!mDestroyThread))
+        {
+          needToSleep    = mNeedToSleep;
+          sleepTimePoint = mSleepTimePoint;
+          mNeedToSleep   = false;
+        }
       }
-    }
-
-    if(needToSleep)
-    {
-      DALI_TRACE_SCOPE(gTraceFilter, "VECTOR_ANIMATION_SLEEP_THREAD");
-
-      std::this_thread::sleep_until(sleepTimePoint);
 
+      if(DALI_LIKELY(!mDestroyThread))
       {
-        Mutex::ScopedLock awakeLock(mAwakeCallbackMutex);
-        if(DALI_LIKELY(mAwakeCallback))
+        DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "VECTOR_ANIMATION_SLEEP_THREAD", [&](std::ostringstream& oss) {
+          oss << "[";
+          if(needToSleep)
+          {
+            auto currentTime = std::chrono::steady_clock::now();
+            auto duration    = std::chrono::duration_cast<std::chrono::milliseconds>(sleepTimePoint - currentTime);
+            oss << duration.count() << " ms]";
+          }
+          else
+          {
+            oss << "until notify]";
+          }
+        });
+
+        if(needToSleep)
+        {
+          mConditionalWait.WaitUntil(lock, sleepTimePoint);
+        }
+        else
         {
-          CallbackBase::Execute(*mAwakeCallback);
+          mConditionalWait.Wait(lock);
         }
+
+        DALI_TRACE_END(gTraceFilter, "VECTOR_ANIMATION_SLEEP_THREAD");
       }
     }
 
+    if(DALI_LIKELY(!mDestroyThread) && needToSleep)
     {
-      ConditionalWait::ScopedLock lock(mConditionalWait);
-      if(DALI_LIKELY(!mDestroyThread) && !mNeedToSleep)
+      Mutex::ScopedLock awakeLock(mAwakeCallbackMutex);
+      if(DALI_LIKELY(mAwakeCallback))
       {
-        DALI_TRACE_SCOPE(gTraceFilter, "VECTOR_ANIMATION_SLEEP_THREAD_WAIT");
-        mConditionalWait.Wait(lock);
+        // Awake out of ConditionalWait::ScopedLock to avoid deadlock.
+        CallbackBase::Execute(*mAwakeCallback);
       }
     }
   }