This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/scheduled_event_on_event_thread
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to 
refs/heads/feature/scheduled_event_on_event_thread by this push:
     new 2b7ab05d Remove nextDeadline output arg from 
celix_scheduledEvent_deadlineReached
2b7ab05d is described below

commit 2b7ab05d7c1dad422d745e50d294c902df9306ab
Author: Pepijn Noltes <[email protected]>
AuthorDate: Mon Jul 3 22:51:09 2023 +0200

    Remove nextDeadline output arg from celix_scheduledEvent_deadlineReached
---
 libs/framework/src/celix_scheduled_event.c | 26 ++++++++++---------
 libs/framework/src/celix_scheduled_event.h | 19 ++++++++------
 libs/framework/src/framework.c             | 40 ++++++++++++++++++++----------
 3 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/libs/framework/src/celix_scheduled_event.c 
b/libs/framework/src/celix_scheduled_event.c
index de944121..ea03e632 100644
--- a/libs/framework/src/celix_scheduled_event.c
+++ b/libs/framework/src/celix_scheduled_event.c
@@ -176,23 +176,25 @@ long celix_scheduledEvent_getId(const 
celix_scheduled_event_t* event) { return e
 long celix_scheduledEvent_getBundleId(const celix_scheduled_event_t* event) { 
return event->bndId; }
 
 bool celix_scheduledEvent_deadlineReached(celix_scheduled_event_t* event,
-                                          const struct timespec* currentTime,
-                                          struct timespec* nextDeadline) {
+                                          const struct timespec* scheduleTime) 
{
     celixThreadMutex_lock(&event->mutex);
-    double timeLeft = celix_difftime(currentTime, &event->nextDeadline);
+    double timeLeft = celix_difftime(scheduleTime, &event->nextDeadline);
     bool deadlineReached = timeLeft - 
CELIX_SCHEDULED_EVENT_INTERVAL_ALLOW_ERROR_IN_SECONDS <= 0;
     if (event->processForWakeup) {
         deadlineReached = true;
     }
-    if (nextDeadline) {
-        *nextDeadline =
-            deadlineReached ? celix_delayedTimespec(currentTime, 
event->intervalInSeconds) : event->nextDeadline;
-    }
     celixThreadMutex_unlock(&event->mutex);
     return deadlineReached;
 }
 
-void celix_scheduledEvent_process(celix_scheduled_event_t* event, const struct 
timespec* currentTime) {
+struct timespec celix_scheduledEvent_getNextDeadline(celix_scheduled_event_t* 
event) {
+    celixThreadMutex_lock(&event->mutex);
+    struct timespec nextDeadline = event->nextDeadline;
+    celixThreadMutex_unlock(&event->mutex);
+    return nextDeadline;
+}
+
+void celix_scheduledEvent_process(celix_scheduled_event_t* event, const struct 
timespec* scheduleTime) {
     fw_log(event->logger,
            CELIX_LOG_LEVEL_TRACE,
            "Processing scheduled event %s for bundle id %li",
@@ -205,7 +207,7 @@ void celix_scheduledEvent_process(celix_scheduled_event_t* 
event, const struct t
     struct timespec end = celix_gettime(CLOCK_MONOTONIC);
 
     celixThreadMutex_lock(&event->mutex);
-    event->nextDeadline = celix_delayedTimespec(currentTime, 
event->intervalInSeconds);
+    event->nextDeadline = celix_delayedTimespec(scheduleTime, 
event->intervalInSeconds);
     event->callCount += 1;
     event->processForWakeup = false;
     celixThreadCondition_broadcast(&event->cond); // for changed callCount
@@ -299,7 +301,7 @@ bool 
celix_scheduledEvent_isMarkedForRemoval(celix_scheduled_event_t* event) {
     return isMarkedForRemoval;
 }
 
-bool celix_scheduledEvent_requiresProcessing(celix_scheduled_event_t* event, 
const struct timespec* currentTime) {
-    return celix_scheduledEvent_deadlineReached(event, currentTime, NULL) ||
+bool celix_scheduledEvent_requiresProcessing(celix_scheduled_event_t* event, 
const struct timespec* scheduleTime) {
+    return celix_scheduledEvent_deadlineReached(event, scheduleTime) ||
            celix_scheduledEvent_isMarkedForRemoval(event);
-}
\ No newline at end of file
+}
diff --git a/libs/framework/src/celix_scheduled_event.h 
b/libs/framework/src/celix_scheduled_event.h
index 77ff37e6..2db1f227 100644
--- a/libs/framework/src/celix_scheduled_event.h
+++ b/libs/framework/src/celix_scheduled_event.h
@@ -113,13 +113,18 @@ long celix_scheduledEvent_getBundleId(const 
celix_scheduled_event_t* event);
 /**
  * @brief Returns whether the event deadline is reached and the event should 
be processed.
  * @param[in] event The event to check.
- * @param[in] currentTime The current time.
- * @param[out] nextDeadline The next deadline. Can be NULL.
+ * @param[in] scheduleTime The schedule time.
  * @return true if the event deadline is reached and the event should be 
processed.
  */
 bool celix_scheduledEvent_deadlineReached(celix_scheduled_event_t* event,
-                                          const struct timespec* currentTime,
-                                          struct timespec* nextDeadline);
+                                          const struct timespec* scheduleTime);
+
+/**
+ * @brief Get the next deadline for the scheduled event.
+ * @param[in] event The event to get the next deadline for.
+ * @return The next deadline for the scheduled event.
+ */
+struct timespec celix_scheduledEvent_getNextDeadline(celix_scheduled_event_t* 
event);
 
 /**
  * @brief Process the event by calling the event callback.
@@ -127,9 +132,9 @@ bool 
celix_scheduledEvent_deadlineReached(celix_scheduled_event_t* event,
  * Must be called on the Celix event thread.
  *
  * @param[in] event The event to process.
- * @param[in] currentTime The current time.
+ * @param[in] scheduleTime The schedule time.
  */
-void celix_scheduledEvent_process(celix_scheduled_event_t* event, const struct 
timespec* currentTime);
+void celix_scheduledEvent_process(celix_scheduled_event_t* event, const struct 
timespec* scheduleTime);
 
 /**
  * @brief Call the removed callback of the event and set the removed flag.
@@ -178,7 +183,7 @@ celix_status_t 
celix_scheduledEvent_wait(celix_scheduled_event_t* event, double
  * @brief Returns true if the event is marked for wakeup, the initial delay or 
interval deadline is reached or the
  * event is marked for removal for the given time.
  */
-bool celix_scheduledEvent_requiresProcessing(celix_scheduled_event_t* event, 
const struct timespec* currentTime);
+bool celix_scheduledEvent_requiresProcessing(celix_scheduled_event_t* event, 
const struct timespec* scheduleTime);
 
 #ifdef __cplusplus
 };
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 63f2740d..f48a706b 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -1407,15 +1407,10 @@ static inline void fw_handleEvents(celix_framework_t* 
framework) {
 /**
  * @brief Process all scheduled events.
  */
-static struct timespec 
celix_framework_processScheduledEvents(celix_framework_t* fw) {
-    struct timespec ts = celixThreadCondition_getTime();
-
-    struct timespec closestDeadline;
+static void celix_framework_processScheduledEvents(celix_framework_t* fw, 
const struct timespec* scheduleTime) {
     celix_scheduled_event_t* callEvent;
     celix_scheduled_event_t* removeEvent;
     do {
-        closestDeadline.tv_sec = 0;
-        closestDeadline.tv_nsec = 0;
         callEvent = NULL;
         removeEvent = NULL;
         celixThreadMutex_lock(&fw->dispatcher.mutex);
@@ -1427,11 +1422,7 @@ static struct timespec 
celix_framework_processScheduledEvents(celix_framework_t*
                 break;
             }
 
-            struct timespec nextDeadline;
-            bool call = celix_scheduledEvent_deadlineReached(visit, &ts, 
&nextDeadline);
-            if (celix_compareTime(&nextDeadline, &closestDeadline) < 0) {
-                closestDeadline = nextDeadline;
-            }
+            bool call = celix_scheduledEvent_deadlineReached(visit, 
scheduleTime);
             if (call) {
                 callEvent = visit;
                 if (celix_scheduledEvent_isSingleShot(visit)) {
@@ -1444,7 +1435,7 @@ static struct timespec 
celix_framework_processScheduledEvents(celix_framework_t*
         celixThreadMutex_unlock(&fw->dispatcher.mutex);
 
         if (callEvent != NULL) {
-            celix_scheduledEvent_process(callEvent, &ts);
+            celix_scheduledEvent_process(callEvent, scheduleTime);
         }
         if (removeEvent != NULL) {
             fw_log(fw->logger,
@@ -1458,7 +1449,25 @@ static struct timespec 
celix_framework_processScheduledEvents(celix_framework_t*
             celix_scheduledEvent_release(removeEvent);
         }
     } while (callEvent || removeEvent);
+}
 
+/**
+ * @brief Calculate the next deadline for scheduled events.
+ * @return The next deadline or a time 0 second and 0 nanoseconds if no 
scheduled events are available.
+ */
+static struct timespec 
celix_framework_nextDeadlineForScheduledEvents(celix_framework_t* framework) {
+    struct timespec closestDeadline = {0,0};
+    celixThreadMutex_lock(&framework->dispatcher.mutex);
+    CELIX_LONG_HASH_MAP_ITERATE(framework->dispatcher.scheduledEvents, entry) {
+        celix_scheduled_event_t *visit = entry.value.ptrValue;
+        struct timespec eventDeadline = 
celix_scheduledEvent_getNextDeadline(visit);
+        if (closestDeadline.tv_sec == 0 && closestDeadline.tv_nsec == 0) {
+            closestDeadline = eventDeadline;
+        } else if (celix_compareTime(&eventDeadline, &closestDeadline) < 0) {
+            closestDeadline = eventDeadline;
+        }
+    }
+    celixThreadMutex_unlock(&framework->dispatcher.mutex);
     return closestDeadline;
 }
 
@@ -1515,6 +1524,9 @@ static bool 
requiresScheduledEventsProcessing(celix_framework_t* framework) {
 }
 
 static void celix_framework_waitForNextEvent(celix_framework_t* fw, struct 
timespec nextDeadline) {
+    if (nextDeadline.tv_sec == 0 && nextDeadline.tv_nsec == 0) {
+        nextDeadline = celixThreadCondition_getDelayedTime(1); //no next 
deadline, wait max 1s
+    }
     celixThreadMutex_lock(&fw->dispatcher.mutex);
     if (celix_framework_eventQueueSize(fw) == 0 && 
!requiresScheduledEventsProcessing(fw) && fw->dispatcher.active) {
         celixThreadCondition_waitUntil(&fw->dispatcher.cond, 
&fw->dispatcher.mutex, &nextDeadline);
@@ -1533,7 +1545,9 @@ static void *fw_eventDispatcher(void *fw) {
 
     while (active) {
         fw_handleEvents(framework);
-        struct timespec nextDeadline = 
celix_framework_processScheduledEvents(framework);
+        struct timespec scheduleTime = celixThreadCondition_getTime();
+        celix_framework_processScheduledEvents(framework, &scheduleTime);
+        struct timespec nextDeadline = 
celix_framework_nextDeadlineForScheduledEvents(framework);
         celix_framework_waitForNextEvent(framework, nextDeadline);
 
         celixThreadMutex_lock(&framework->dispatcher.mutex);

Reply via email to