changeset 7177:e4bf724a5886

added PeriodicRunnableThread::SetTimeResolution()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 21 Oct 2026 15:11:24 +0200
parents 240c8c844a7d
children 67a629f02859
files OrthancFramework/Sources/MultiThreading/PeriodicRunnableThread.cpp OrthancFramework/Sources/MultiThreading/PeriodicRunnableThread.h
diffstat 2 files changed, 47 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/MultiThreading/PeriodicRunnableThread.cpp	Wed Oct 21 14:58:45 2026 +0200
+++ b/OrthancFramework/Sources/MultiThreading/PeriodicRunnableThread.cpp	Wed Oct 21 15:11:24 2026 +0200
@@ -28,8 +28,16 @@
 
 namespace Orthanc
 {
+  static boost::posix_time::ptime GetNow()
+  {
+    return boost::posix_time::microsec_clock::universal_time();
+  }
+
+
   void PeriodicRunnableThread::Worker(PeriodicRunnableThread* that)
   {
+    boost::posix_time::ptime nextExecutionTime = GetNow();
+
     for (;;)
     {
       {
@@ -40,11 +48,19 @@
         }
       }
 
-      that->runnable_->Run();
+      const boost::posix_time::ptime now = GetNow();
 
-      if (that->timeResolution_ != 0)
+      if (now >= nextExecutionTime)
       {
-        boost::this_thread::sleep(boost::posix_time::milliseconds(that->timeResolution_));
+        that->runnable_->Run();
+        nextExecutionTime = now + boost::posix_time::milliseconds(that->delay_);
+      }
+      else
+      {
+        if (that->timeResolution_ != 0)
+        {
+          boost::this_thread::sleep(boost::posix_time::milliseconds(that->timeResolution_));
+        }
       }
     }
   }
@@ -76,9 +92,10 @@
 
 
   PeriodicRunnableThread::PeriodicRunnableThread(IRunnable* runnable,
-                                                 unsigned int timeResolution) :
+                                                 unsigned int delay) :
     runnable_(runnable),
-    timeResolution_(timeResolution),
+    delay_(delay),
+    timeResolution_(50),  // By default, use a time granularity of 50ms
     state_(State_Initialization)
   {
     if (runnable == NULL)
@@ -88,6 +105,21 @@
   }
 
 
+  void PeriodicRunnableThread::SetTimeResolution(unsigned int resolution)
+  {
+    boost::mutex::scoped_lock lock(mutex_);
+
+    if (state_ != State_Initialization)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      timeResolution_ = resolution;
+    }
+  }
+
+
   void PeriodicRunnableThread::Start()
   {
     boost::mutex::scoped_lock lock(mutex_);
--- a/OrthancFramework/Sources/MultiThreading/PeriodicRunnableThread.h	Wed Oct 21 14:58:45 2026 +0200
+++ b/OrthancFramework/Sources/MultiThreading/PeriodicRunnableThread.h	Wed Oct 21 15:11:24 2026 +0200
@@ -48,19 +48,27 @@
 
     boost::mutex                mutex_;
     std::unique_ptr<IRunnable>  runnable_;
-    unsigned int                timeResolution_;
+    unsigned int                delay_;  // In milliseconds
+    unsigned int                timeResolution_;  // In milliseconds
     volatile State              state_;
     boost::thread               thread_;
 
   public:
     PeriodicRunnableThread(IRunnable* runnable /* takes ownership */,
-                           unsigned int timeResolution);
+                           unsigned int delay /* number of milliseconds between 2 executions */);
 
     ~PeriodicRunnableThread()
     {
       StopInternal(false /* no exception in destructors */);
     }
 
+    /**
+     * Set the granularity (in milliseconds) at which "Stop()" is
+     * checked for while waiting between two executions of the
+     * runnable, can be useful for testing.
+     **/
+    void SetTimeResolution(unsigned int resolution);
+
     void Start();
 
     void Stop()