Просмотр исходного кода

move computation of the timeout to the server

Julius Pfrommer лет назад: 8
Родитель
Сommit
4a5b316d7d
3 измененных файлов с 28 добавлено и 31 удалено
  1. 5 0
      src/server/ua_server_worker.c
  2. 19 21
      src/ua_timer.c
  3. 4 10
      src/ua_timer.h

+ 5 - 0
src/server/ua_server_worker.c

@@ -40,6 +40,8 @@
  *     memory models." ACM SIGPLAN Notices. Vol. 48. No. 8. ACM, 2013.
  */
 
+#define UA_MAXTIMEOUT 50 // max timeout in millisec until the next main loop iteration
+
 #ifdef UA_ENABLE_DISCOVERY_MULTICAST
 # ifndef _WIN32
 #  include <unistd.h> // gethostname
@@ -444,6 +446,9 @@ UA_UInt16 UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal) {
     UA_Boolean dispatched = false; /* to wake up worker threads */
     UA_DateTime nextRepeated =
         UA_RepeatedJobsList_process(&server->repeatedJobs, now, &dispatched);
+    UA_DateTime latest = now + (UA_MAXTIMEOUT * UA_MSEC_TO_DATETIME);
+    if(nextRepeated > latest)
+        nextRepeated = latest;
 
     UA_UInt16 timeout = 0;
     if(waitInternal)

+ 19 - 21
src/ua_timer.c

@@ -5,8 +5,6 @@
 #include "ua_util.h"
 #include "ua_timer.h"
 
-#define MAXTIMEOUT 50 // max timeout in millisec until the next main loop iteration
-
 /* Only one thread may traverse the lists. This is usually the "main" thread
  * with the event loop. All other threads may add and remove repeated jobs by
  * adding entries to the beginning of the addRemoveJobs list (with atomic
@@ -31,6 +29,16 @@ struct UA_RepeatedJob {
     UA_Job job;                       /* The job description itself */
 };
 
+void
+UA_RepeatedJobsList_init(UA_RepeatedJobsList *rjl,
+                         UA_RepeatedJobsListProcessCallback processCallback,
+                         void *processContext) {
+    SLIST_INIT(&rjl->repeatedJobs);
+    SLIST_INIT(&rjl->addRemoveJobs);
+    rjl->processCallback = processCallback;
+    rjl->processContext = processContext;
+}
+
 UA_StatusCode
 UA_RepeatedJobsList_addRepeatedJob(UA_RepeatedJobsList *rjl, const UA_Job job,
                                    const UA_UInt32 interval, UA_Guid *jobId) {
@@ -38,19 +46,16 @@ UA_RepeatedJobsList_addRepeatedJob(UA_RepeatedJobsList *rjl, const UA_Job job,
     if(interval < 5)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    /* From ms to 100ns resolution */
-    UA_UInt64 interval_dt = (UA_UInt64)interval * (UA_UInt64)UA_MSEC_TO_DATETIME;
-
     /* Allocate the repeated job structure */
     UA_RepeatedJob *rj = (UA_RepeatedJob*)UA_malloc(sizeof(UA_RepeatedJob));
     if(!rj)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
     /* Set the repeated job */
-    rj->interval = interval_dt;
+    rj->interval = (UA_UInt64)interval * (UA_UInt64)UA_MSEC_TO_DATETIME;
     rj->id = UA_Guid_random();
     rj->job = job;
-    rj->nextTime = UA_DateTime_nowMonotonic() + (UA_DateTime)interval_dt;
+    rj->nextTime = UA_DateTime_nowMonotonic() + (UA_DateTime)rj->interval;
 
     /* Set the output guid */
     if(jobId)
@@ -134,17 +139,6 @@ removeRepeatedJob(UA_RepeatedJobsList *rjl, const UA_Guid *jobId) {
     }
 }
 
-static UA_DateTime
-nextRepetition(const UA_RepeatedJobsList *rjl, UA_DateTime nowMonotonic) {
-    /* Check if the next repeated job is sooner than the usual timeout.
-     * Return the duration until the next job or the max interval. */
-    UA_RepeatedJob *first = SLIST_FIRST(&rjl->repeatedJobs);
-    UA_DateTime next = nowMonotonic + (MAXTIMEOUT * UA_MSEC_TO_DATETIME);
-    if(first && first->nextTime < next)
-        next = first->nextTime;
-    return next;
-}
-
 static void
 processAddRemoveJobs(UA_RepeatedJobsList *rjl, UA_DateTime nowMonotonic) {
     UA_RepeatedJob *current;
@@ -175,8 +169,12 @@ UA_RepeatedJobsList_process(UA_RepeatedJobsList *rjl,
     }
 
     /* Nothing to do */
-    if(!lastNow)
-        return nextRepetition(rjl, nowMonotonic);
+    if(!lastNow) {
+        if(firstAfter)
+            return firstAfter->nextTime;
+        else
+            return UA_INT64_MAX;
+    }
 
     /* Put the jobs that are executed now in a separate list */
     struct memberstruct(UA_RepeatedJobsList,RepeatedJobsSList) executedNowList;
@@ -239,7 +237,7 @@ UA_RepeatedJobsList_process(UA_RepeatedJobsList *rjl,
     processAddRemoveJobs(rjl, nowMonotonic);
 
     /* Return timestamp of next repetition */
-    return nextRepetition(rjl, nowMonotonic);
+    return SLIST_FIRST(&rjl->repeatedJobs)->nextTime;
 }
 
 void

+ 4 - 10
src/ua_timer.h

@@ -28,15 +28,10 @@ typedef struct {
     void *processContext;
 } UA_RepeatedJobsList;
 
-static UA_INLINE void
+void
 UA_RepeatedJobsList_init(UA_RepeatedJobsList *rjl,
                          UA_RepeatedJobsListProcessCallback processCallback,
-                         void *processContext) {
-    SLIST_INIT(&rjl->repeatedJobs);
-    SLIST_INIT(&rjl->addRemoveJobs);
-    rjl->processCallback = processCallback;
-    rjl->processContext = processContext;
-}
+                         void *processContext);
 
 UA_StatusCode
 UA_RepeatedJobsList_addRepeatedJob(UA_RepeatedJobsList *rjl, const UA_Job job,
@@ -45,9 +40,8 @@ UA_RepeatedJobsList_addRepeatedJob(UA_RepeatedJobsList *rjl, const UA_Job job,
 UA_StatusCode
 UA_RepeatedJobsList_removeRepeatedJob(UA_RepeatedJobsList *rjl, const UA_Guid jobId);
 
-/* - Processed all repeated jobs that have timed out
- * - Reinserts dispatched job at their new position in the sorted list
- * - Returns the next datetime when a repeated job is scheduled */
+/* Process the repeated jobs that have timed out.
+ * Returns the timestamp of the next scheduled repeated job. */
 UA_DateTime
 UA_RepeatedJobsList_process(UA_RepeatedJobsList *rjl, UA_DateTime nowMonotonic,
                             UA_Boolean *dispatched);