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);