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

commit 47d49d5f116c0867fd5586e41bbd1549cfa35176
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sat Jun 17 15:36:42 2023 +0200

    Refactor scheduled event to use celixThreadCondition_getTime
---
 .../src/CelixBundleContextServicesTestSuite.cc     |  2 +-
 .../framework/gtest/src/CelixFrameworkTestSuite.cc |  2 +-
 .../framework/gtest/src/ScheduledEventTestSuite.cc | 10 +--
 libs/framework/include/celix/ScheduledEvent.h      |  1 +
 libs/framework/include/celix_bundle_context.h      |  2 +-
 libs/framework/include/celix_framework.h           |  2 +-
 libs/framework/src/celix_scheduled_event.c         | 25 +++-----
 libs/framework/src/celix_scheduled_event.h         |  5 +-
 libs/framework/src/framework.c                     | 75 ++++++++++++----------
 libs/framework/src/framework_private.h             |  2 +-
 libs/utils/gtest/src/ThreadsTestSuite.cc           | 12 ++--
 libs/utils/include/celix_errno.h                   |  1 -
 libs/utils/include/celix_threads.h                 |  7 +-
 libs/utils/src/celix_threads.c                     | 11 ++--
 14 files changed, 82 insertions(+), 75 deletions(-)

diff --git a/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc 
b/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
index e5351d4b..f9115f41 100644
--- a/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
+++ b/libs/framework/gtest/src/CelixBundleContextServicesTestSuite.cc
@@ -477,7 +477,7 @@ TEST_F(CelixBundleContextServicesTestSuite, 
UseServiceInUseCallbackTest) {
     celix_bundleContext_unregisterService(ctx, svcId3);
 }
 
-TEST_F(CelixBundleContextServicesTestSuite, TegisterAndUseServiceTest) {
+TEST_F(CelixBundleContextServicesTestSuite, RegisterAndUseServiceTest) {
     struct calc {
         int (*calc)(int);
     };
diff --git a/libs/framework/gtest/src/CelixFrameworkTestSuite.cc 
b/libs/framework/gtest/src/CelixFrameworkTestSuite.cc
index b187453a..7085f7b4 100644
--- a/libs/framework/gtest/src/CelixFrameworkTestSuite.cc
+++ b/libs/framework/gtest/src/CelixFrameworkTestSuite.cc
@@ -91,7 +91,7 @@ TEST_F(CelixFrameworkTestSuite, TimedWaitEventQueueTest) {
 
     //Then a wait for empty event queue for max 5ms will return a timeout
     celix_status_t status = 
celix_framework_timedWaitForEmptyEventQueue(framework.get(), 0.005);
-    EXPECT_EQ(CELIX_TIMEOUT, status);
+    EXPECT_EQ(ETIMEDOUT, status);
 
     //And a wait for empty event queue for max 30ms will return success
     status = celix_framework_timedWaitForEmptyEventQueue(framework.get(), 
0.03);
diff --git a/libs/framework/gtest/src/ScheduledEventTestSuite.cc 
b/libs/framework/gtest/src/ScheduledEventTestSuite.cc
index 9b52fc2e..1459fc2e 100644
--- a/libs/framework/gtest/src/ScheduledEventTestSuite.cc
+++ b/libs/framework/gtest/src/ScheduledEventTestSuite.cc
@@ -384,7 +384,7 @@ TEST_F(ScheduledEventTestSuite, CxxScheduledEventRAIITest) {
     auto removeCallback = [&removed]() { removed.store(true); };
 
     {
-        // And a scoped scheduled event with a initial delay and interval of 
100ms
+        // And a scoped scheduled event with an initial delay and interval of 
50ms
         auto event = fw->getFrameworkBundleContext()
                          ->scheduledEvent()
                          .withName("test cxx")
@@ -402,10 +402,10 @@ TEST_F(ScheduledEventTestSuite, 
CxxScheduledEventRAIITest) {
     // When waiting longer than the initial delay
     std::this_thread::sleep_for(std::chrono::milliseconds{60});
 
-    // When the remove callback is called
+    // Then the remove callback is called
     EXPECT_TRUE(removed.load());
 
-    // Then the count is not increased
+    // And the count is not increased
     EXPECT_EQ(0, count.load());
 }
 
@@ -449,6 +449,8 @@ TEST_F(ScheduledEventTestSuite, 
CxxOneShotScheduledEventTest) {
 
     // Then the count is not increased, because the event is a one-shot event
     EXPECT_EQ(1, count.load());
+
+    // When the event goes out of scope, it does not leak
 }
 
 TEST_F(ScheduledEventTestSuite, CxxOneShotScheduledEventRAIITest) {
@@ -563,7 +565,7 @@ TEST_F(ScheduledEventTestSuite, WaitForScheduledEvent) {
     status = 
celix_bundleContext_waitForScheduledEvent(fw->getFrameworkBundleContext()->getCBundleContext(),
 eventId, 0.0001);
 
     //Then the return status is timeout
-    EXPECT_EQ(CELIX_TIMEOUT, status);
+    EXPECT_EQ(ETIMEDOUT, status);
 
     //When waiting for the event with a timeout longer than the interval
     status = 
celix_bundleContext_waitForScheduledEvent(fw->getFrameworkBundleContext()->getCBundleContext(),
 eventId, 0.0012);
diff --git a/libs/framework/include/celix/ScheduledEvent.h 
b/libs/framework/include/celix/ScheduledEvent.h
index 06c52684..a20afb10 100644
--- a/libs/framework/include/celix/ScheduledEvent.h
+++ b/libs/framework/include/celix/ScheduledEvent.h
@@ -124,6 +124,7 @@ class ScheduledEvent final {
             if (callbacks->removeCallback) {
                 (callbacks->removeCallback)();
             }
+            delete callbacks;
         };
 
         ctx = std::move(_cCtx);
diff --git a/libs/framework/include/celix_bundle_context.h 
b/libs/framework/include/celix_bundle_context.h
index 26829c6b..d3b761f9 100644
--- a/libs/framework/include/celix_bundle_context.h
+++ b/libs/framework/include/celix_bundle_context.h
@@ -1334,7 +1334,7 @@ CELIX_FRAMEWORK_EXPORT celix_status_t 
celix_bundleContext_wakeupScheduledEvent(c
  * @param[in] waitTimeInSeconds The maximum time to wait for the next 
scheduled event. If <= 0 the function will return
  *                             immediately.
  * @return CELIX_SUCCESS if the scheduled event is woken up, 
CELIX_ILLEGAL_ARGUMENT if the scheduled event id is not
- *         known and CELIX_TIMEOUT if the waitTimeInSeconds is reached.
+ *         known and ETIMEDOUT if the waitTimeInSeconds is reached.
  */
 CELIX_FRAMEWORK_EXPORT celix_status_t 
celix_bundleContext_waitForScheduledEvent(celix_bundle_context_t* ctx,
                                                                                
 long scheduledEventId,
diff --git a/libs/framework/include/celix_framework.h 
b/libs/framework/include/celix_framework.h
index 6cfd0206..d1d47cf5 100644
--- a/libs/framework/include/celix_framework.h
+++ b/libs/framework/include/celix_framework.h
@@ -348,7 +348,7 @@ CELIX_FRAMEWORK_EXPORT void 
celix_framework_waitForEmptyEventQueue(celix_framewo
  *
  * @param[in] fw The Celix Framework.
  * @param[in] timeoutInSeconds The period in seconds to wait for the event 
queue to be empty. 0 means wait forever.
- * @return CELIX_SUCCESS if the event queue is empty or CELIX_TIMEOUT if the 
timeoutInSeconds is reached.
+ * @return CELIX_SUCCESS if the event queue is empty or ETIMEDOUT if the 
timeoutInSeconds is reached.
  */
 CELIX_FRAMEWORK_EXPORT celix_status_t 
celix_framework_timedWaitForEmptyEventQueue(celix_framework_t *fw, double 
timeoutInSeconds);
 
diff --git a/libs/framework/src/celix_scheduled_event.c 
b/libs/framework/src/celix_scheduled_event.c
index d2707e28..ab4a065d 100644
--- a/libs/framework/src/celix_scheduled_event.c
+++ b/libs/framework/src/celix_scheduled_event.c
@@ -119,7 +119,7 @@ celix_scheduled_event_t* 
celix_scheduledEvent_create(celix_framework_logger_t* l
     event->useCount = 1;
     event->callCount = 0;
     event->isRemoved = false;
-    event->lastScheduledEventTime = celix_gettime(CLOCK_REALTIME);
+    event->lastScheduledEventTime = celixThreadCondition_getTime();
     event->processForWakeup = false;
 
     celixThreadMutex_create(&event->mutex, NULL);
@@ -240,14 +240,11 @@ celix_status_t 
celix_scheduledEvent_waitForAtLeastCallCount(celix_scheduled_even
                                                             double 
waitTimeInSeconds) {
     celix_status_t status = CELIX_SUCCESS;
     if (waitTimeInSeconds > 0) {
-        struct timespec start = celix_gettime(CLOCK_REALTIME);
-        struct timespec absTimeoutTime = celix_delayedTimespec(&start, 
waitTimeInSeconds);
+        struct timespec absTime= 
celixThreadCondition_getDelayedTime(waitTimeInSeconds);
         celixThreadMutex_lock(&event->mutex);
         while (event->callCount < targetCallCount) {
-            celixThreadCondition_waitUntil(&event->cond, &event->mutex, 
&absTimeoutTime);
-            struct timespec now = celix_gettime(CLOCK_REALTIME);
-            if (celix_difftime(&start, &now) > waitTimeInSeconds) {
-                status = CELIX_TIMEOUT;
+            status = celixThreadCondition_waitUntil(&event->cond, 
&event->mutex, &absTime);
+            if (status == ETIMEDOUT) {
                 break;
             }
         }
@@ -257,8 +254,7 @@ celix_status_t 
celix_scheduledEvent_waitForAtLeastCallCount(celix_scheduled_even
 }
 
 void celix_scheduledEvent_waitForRemoved(celix_scheduled_event_t* event) {
-    struct timespec start = celix_gettime(CLOCK_REALTIME);
-    struct timespec absLogTimeout = celix_delayedTimespec(&start, 
CELIX_SCHEDULED_EVENT_ERROR_LOG_TIMEOUT_IN_SECONDS);
+    struct timespec absLogTimeout = 
celixThreadCondition_getDelayedTime(CELIX_SCHEDULED_EVENT_ERROR_LOG_TIMEOUT_IN_SECONDS);
     celixThreadMutex_lock(&event->mutex);
     while (!event->isRemoved) {
         celix_status_t waitStatus = 
celixThreadCondition_waitUntil(&event->cond, &event->mutex, &absLogTimeout);
@@ -269,8 +265,7 @@ void 
celix_scheduledEvent_waitForRemoved(celix_scheduled_event_t* event) {
                    event->eventName,
                    event->scheduledEventId,
                    event->bndId);
-            start = celix_gettime(CLOCK_REALTIME);
-            absLogTimeout = celix_delayedTimespec(&start, 
CELIX_SCHEDULED_EVENT_ERROR_LOG_TIMEOUT_IN_SECONDS);
+            absLogTimeout = 
celixThreadCondition_getDelayedTime(CELIX_SCHEDULED_EVENT_ERROR_LOG_TIMEOUT_IN_SECONDS);
         }
     }
     celixThreadMutex_unlock(&event->mutex);
@@ -280,12 +275,10 @@ celix_status_t 
celix_scheduledEvent_wait(celix_scheduled_event_t* event, double
     celix_status_t status = CELIX_SUCCESS;
     celixThreadMutex_lock(&event->mutex);
     size_t targetCallCount = event->callCount + 1;
-    struct timespec start = celix_gettime(CLOCK_REALTIME);
-    struct timespec absTimeoutTime = celix_delayedTimespec(&start, 
timeoutInSeconds);
+    struct timespec absTimeoutTime = 
celixThreadCondition_getDelayedTime(timeoutInSeconds);
     while (event->callCount < targetCallCount) {
-        celix_status_t waitStatus = 
celixThreadCondition_waitUntil(&event->cond, &event->mutex, &absTimeoutTime);
-        if (waitStatus == ETIMEDOUT) {
-            status = CELIX_TIMEOUT;
+        status = celixThreadCondition_waitUntil(&event->cond, &event->mutex, 
&absTimeoutTime);
+        if (status == ETIMEDOUT) {
             break;
         }
     }
diff --git a/libs/framework/src/celix_scheduled_event.h 
b/libs/framework/src/celix_scheduled_event.h
index 5b0e79fc..6446fcbe 100644
--- a/libs/framework/src/celix_scheduled_event.h
+++ b/libs/framework/src/celix_scheduled_event.h
@@ -146,7 +146,7 @@ size_t 
celix_scheduledEvent_markForWakeup(celix_scheduled_event_t* event);
  * @param[in] event The event to wait for.
  * @param[in] callCount The call count to wait for.
  * @param[in] timeout The max time to wait in seconds.
- * @return CELIX_SUCCESS if the scheduled event reached the call count, 
CELIX_TIMEOUT if the scheduled event
+ * @return CELIX_SUCCESS if the scheduled event reached the call count, 
ETIMEDOUT if the scheduled event
  */
 celix_status_t 
celix_scheduledEvent_waitForAtLeastCallCount(celix_scheduled_event_t* event,
                                                             size_t 
targetCallCount,
@@ -156,7 +156,8 @@ celix_status_t 
celix_scheduledEvent_waitForAtLeastCallCount(celix_scheduled_even
  * @brief Wait for a scheduled event to be done with the next scheduled 
processing.
  * @param[in] event The event to wait for.
  * @param[in] timeoutInSeconds The max time to wait in seconds. Must be > 0.
- * @return CELIX_SUCCESS if the scheduled event is done with processing, 
CELIX_TIMEOUT if the scheduled event.
+ * @return CELIX_SUCCESS if the scheduled event is done with processing, 
ETIMEDOUT if the scheduled event is not
+ *        done with processing within the timeout.
  */
 celix_status_t celix_scheduledEvent_wait(celix_scheduled_event_t* event, 
double timeoutInSeconds);
 
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 3a7619a1..62dfbf95 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -73,15 +73,18 @@ static inline celix_framework_bundle_entry_t* 
fw_bundleEntry_create(celix_bundle
 
 static inline void 
fw_bundleEntry_waitTillUseCountIs(celix_framework_bundle_entry_t *entry, size_t 
desiredUseCount) {
     celixThreadMutex_lock(&entry->useMutex);
-    struct timespec start = celix_gettime(CLOCK_MONOTONIC);
+    struct timespec logTimeout = celixThreadCondition_getDelayedTime(5);
     while (entry->useCount != desiredUseCount) {
-        celixThreadCondition_timedwaitRelative(&entry->useCond, 
&entry->useMutex, 5, 0);
-        if (entry->useCount != desiredUseCount) {
-            struct timespec now = celix_gettime(CLOCK_MONOTONIC);
-            if (celix_difftime(&start, &now) > 5) {
-                fw_log(celix_frameworkLogger_globalLogger(), 
CELIX_LOG_LEVEL_WARNING, "Bundle '%s' (bnd id = %li) still in use. Use count is 
%zu, desired is %zu", celix_bundle_getSymbolicName(entry->bnd), entry->bndId, 
entry->useCount, desiredUseCount);
-                start = celix_gettime(CLOCK_MONOTONIC);
-            }
+        celix_status_t waitStatus = 
celixThreadCondition_waitUntil(&entry->useCond, &entry->useMutex, &logTimeout);
+        if (waitStatus == ETIMEDOUT) {
+            fw_log(celix_frameworkLogger_globalLogger(),
+                   CELIX_LOG_LEVEL_WARNING,
+                   "Bundle '%s' (bnd id = %li) still in use. Use count is %zu, 
desired is %zu",
+                   celix_bundle_getSymbolicName(entry->bnd),
+                   entry->bndId,
+                   entry->useCount,
+                   desiredUseCount);
+            logTimeout = celixThreadCondition_getDelayedTime(5);
         }
     }
     celixThreadMutex_unlock(&entry->useMutex);
@@ -1447,7 +1450,7 @@ static inline void fw_handleEvents(celix_framework_t* 
framework) {
  * @brief Process all scheduled events.
  */
 static double celix_framework_processScheduledEvents(celix_framework_t* fw) {
-    struct timespec ts = celix_gettime(CLOCK_REALTIME);
+    struct timespec ts = celixThreadCondition_getTime();
 
     double nextClosestScheduledEvent;
     celix_scheduled_event_t* callEvent;
@@ -2521,8 +2524,7 @@ celix_status_t 
celix_framework_timedWaitForEmptyEventQueue(celix_framework_t *fw
     while (fw->dispatcher.eventQueueSize > 0 || 
celix_arrayList_size(fw->dispatcher.dynamicEventQueue) > 0) {
         if (periodInSeconds > 0) {
             status = 
celixThreadCondition_timedwaitRelative(&fw->dispatcher.cond, 
&fw->dispatcher.mutex, seconds, nanoseconds);
-            if (status != CELIX_SUCCESS) {
-                status = CELIX_TIMEOUT;
+            if (status == ETIMEDOUT) {
                 break;
             }
         } else {
@@ -2744,30 +2746,37 @@ long celix_framework_nextScheduledEventId(framework_t 
*fw) {
     return __atomic_fetch_add(&fw->dispatcher.nextScheduledEventId, 1, 
__ATOMIC_RELAXED);
 }
 
-void celix_framework_waitForGenericEvent(framework_t *fw, long eventId) {
-    assert(!celix_framework_isCurrentThreadTheEventLoop(fw));
-
-    celixThreadMutex_lock(&fw->dispatcher.mutex);
-    bool eventInProgress = true;
-    while (eventInProgress) {
-        eventInProgress = false;
-        for (int i = 0; i < fw->dispatcher.eventQueueSize; ++i) {
-            int index = (fw->dispatcher.eventQueueFirstEntry + i) % 
fw->dispatcher.eventQueueCap;
-            celix_framework_event_t* e = &fw->dispatcher.eventQueue[index];
-            if (e->type == CELIX_GENERIC_EVENT && e->genericEventId == 
eventId) {
-                eventInProgress = true;
-                break;
-            }
+/**
+ * @brief Checks if a generic event with the provided eventId is in progress.
+ */
+static bool celix_framework_isGenericEventInProgress(celix_framework_t* fw, 
long eventId) {
+    // precondition fw->dispatcher.mutex locked)
+    for (int i = 0; i < fw->dispatcher.eventQueueSize; ++i) {
+        int index = (fw->dispatcher.eventQueueFirstEntry + i) % 
fw->dispatcher.eventQueueCap;
+        celix_framework_event_t* e = &fw->dispatcher.eventQueue[index];
+        if (e->type == CELIX_GENERIC_EVENT && e->genericEventId == eventId) {
+            return true;;
         }
-        for (int i = 0; !eventInProgress && i < 
celix_arrayList_size(fw->dispatcher.dynamicEventQueue); ++i) {
-            celix_framework_event_t* e = 
celix_arrayList_get(fw->dispatcher.dynamicEventQueue, i);
-            if (e->type == CELIX_GENERIC_EVENT && e->genericEventId == 
eventId) {
-                eventInProgress = true;
-                break;
-            }
+    }
+    for (int i = 0; i < 
celix_arrayList_size(fw->dispatcher.dynamicEventQueue); ++i) {
+        celix_framework_event_t* e = 
celix_arrayList_get(fw->dispatcher.dynamicEventQueue, i);
+        if (e->type == CELIX_GENERIC_EVENT && e->genericEventId == eventId) {
+            return true;
         }
-        if (eventInProgress) {
-            celixThreadCondition_timedwaitRelative(&fw->dispatcher.cond, 
&fw->dispatcher.mutex, 5, 0);
+    }
+    return false;
+}
+
+void celix_framework_waitForGenericEvent(celix_framework_t* fw, long eventId) {
+    assert(!celix_framework_isCurrentThreadTheEventLoop(fw));
+    struct timespec logAbsTime = celixThreadCondition_getDelayedTime(5);
+    celixThreadMutex_lock(&fw->dispatcher.mutex);
+    while (celix_framework_isGenericEventInProgress(fw, eventId)) {
+        celix_status_t waitStatus =
+            celixThreadCondition_waitUntil(&fw->dispatcher.cond, 
&fw->dispatcher.mutex, &logAbsTime);
+        if (waitStatus == ETIMEDOUT) {
+            fw_log(fw->logger, CELIX_LOG_LEVEL_WARNING, "Generic event with id 
%li not finished.", eventId);
+            logAbsTime = celixThreadCondition_getDelayedTime(5);
         }
     }
     celixThreadMutex_unlock(&fw->dispatcher.mutex);
diff --git a/libs/framework/src/framework_private.h 
b/libs/framework/src/framework_private.h
index acf6f8ac..2482b352 100644
--- a/libs/framework/src/framework_private.h
+++ b/libs/framework/src/framework_private.h
@@ -495,7 +495,7 @@ celix_status_t 
celix_framework_wakeupScheduledEvent(celix_framework_t* fw, long
  * @param[in] waitTimeInSeconds The maximum time to wait for the next 
scheduled event. If <= 0 the function will return
  *                             immediately.
  * @return CELIX_SUCCESS if the scheduled event is woken up, 
CELIX_ILLEGAL_ARGUMENT if the scheduled event id is not
- *         known and CELIX_TIMEOUT if the waitTimeInSeconds is reached.
+ *         known and ETIMEDOUT if the waitTimeInSeconds is reached.
  */
 celix_status_t celix_framework_waitForScheduledEvent(celix_framework_t* fw,
                                                      long scheduledEventId,
diff --git a/libs/utils/gtest/src/ThreadsTestSuite.cc 
b/libs/utils/gtest/src/ThreadsTestSuite.cc
index d19baa00..14f7ce9a 100644
--- a/libs/utils/gtest/src/ThreadsTestSuite.cc
+++ b/libs/utils/gtest/src/ThreadsTestSuite.cc
@@ -303,14 +303,14 @@ TEST_F(ThreadsTestSuite, CondTimedWaitTest) {
     ASSERT_EQ(status, CELIX_ILLEGAL_ARGUMENT);
 
     //Test with valid abstime
-    auto start = celix_gettime(CLOCK_REALTIME);
-    auto targetEnd = celix_delayedTimespec(&start, 0.001);
-    pthread_mutex_lock(&mutex);
+    auto start = celixThreadCondition_getTime();
+    auto targetEnd = celixThreadCondition_getDelayedTime(0.01);
+    celixThreadMutex_lock(&mutex);
     status = celixThreadCondition_waitUntil(&cond, &mutex, &targetEnd);
     ASSERT_EQ(status, ETIMEDOUT);
-    pthread_mutex_unlock(&mutex);
-    auto end = celix_gettime(CLOCK_REALTIME);
-    EXPECT_NEAR(celix_difftime(&end, &start), 0.001, 0.01);
+    celixThreadMutex_unlock(&mutex);
+    auto end = celixThreadCondition_getTime();
+    EXPECT_NEAR(celix_difftime(&end, &start), 0.001, 0.02);
 }
 
 TEST_F(ThreadsTestSuite, CondWaitForTest) {
diff --git a/libs/utils/include/celix_errno.h b/libs/utils/include/celix_errno.h
index 0ebdee28..e942afb0 100644
--- a/libs/utils/include/celix_errno.h
+++ b/libs/utils/include/celix_errno.h
@@ -195,7 +195,6 @@ CELIX_UTILS_EXPORT bool 
celix_utils_isCustomerStatusCode(celix_status_t code);
 #define CELIX_FRAMEWORK_EXCEPTION       
CELIX_ERROR_MAKE(CELIX_FACILITY_FRAMEWORK, 4471)
 #define CELIX_FILE_IO_EXCEPTION         
CELIX_ERROR_MAKE(CELIX_FACILITY_FRAMEWORK, 4472)
 #define CELIX_SERVICE_EXCEPTION         
CELIX_ERROR_MAKE(CELIX_FACILITY_FRAMEWORK, 4473)
-#define CELIX_TIMEOUT                   
CELIX_ERROR_MAKE(CELIX_FACILITY_FRAMEWORK, 4474)
 
 /*!
  * Exception indicating a problem with a interceptor
diff --git a/libs/utils/include/celix_threads.h 
b/libs/utils/include/celix_threads.h
index 72dbcfa2..5f63c661 100644
--- a/libs/utils/include/celix_threads.h
+++ b/libs/utils/include/celix_threads.h
@@ -158,7 +158,7 @@ CELIX_UTILS_EXPORT celix_status_t 
celixThreadCondition_waitFor(celix_thread_cond
  *
  * @return The current time.
  */
-CELIX_UTILS_EXPORT struct timespec celix_threadCondition_getTime();
+CELIX_UTILS_EXPORT struct timespec celixThreadCondition_getTime();
 
 /**
  * @brief Returns the current time plus the given delayInSeconds.
@@ -170,7 +170,7 @@ CELIX_UTILS_EXPORT struct timespec 
celix_threadCondition_getTime();
  * @param delayInSeconds The delay in seconds to add to the current time.
  * @return The current time plus the given delayInSeconds.
  */
-CELIX_UTILS_EXPORT struct timespec celix_threadCondition_getDelayedTime(double 
delayInSeconds);
+CELIX_UTILS_EXPORT struct timespec celixThreadCondition_getDelayedTime(double 
delayInSeconds);
 
 /**
  * @brief Wait for the condition to be signaled or until the given absolute 
time is reached.
@@ -181,7 +181,8 @@ CELIX_UTILS_EXPORT struct timespec 
celix_threadCondition_getDelayedTime(double d
  * - ENOTRECOVERABLE if the state protected by the mutex is not recoverable.
  * - ETIMEDOUT If the abstime has passed.
  *
- *  Values for abstime can be obtained by adding a delay to the current time 
obtained using gettimeofday(2)
+ *  Values for abstime should be obtained by celixThreadCondition_getTime, 
celixThreadCondition_getDelayedTime or
+ *  a modified timespec based on 
celixThreadCondition_getTime/celixThreadCondition_getDelayedTime.
  * 
  * @param[in] cond The condition to wait for.
  * @param[in] mutex The (locked) mutex to use.
diff --git a/libs/utils/src/celix_threads.c b/libs/utils/src/celix_threads.c
index bd540818..407d674a 100644
--- a/libs/utils/src/celix_threads.c
+++ b/libs/utils/src/celix_threads.c
@@ -182,7 +182,8 @@ celix_status_t 
celixThreadCondition_timedwaitRelative(celix_thread_cond_t *cond,
 }
 #else
 celix_status_t celixThreadCondition_timedwaitRelative(celix_thread_cond_t 
*cond, celix_thread_mutex_t *mutex, long seconds, long nanoseconds) {
-    struct timespec time = celix_threadCondition_getTime();
+    double delay = (double)seconds + ((double)nanoseconds / 1000000000);
+    struct timespec time = celixThreadCondition_getDelayedTime(delay);
     return pthread_cond_timedwait(cond, mutex, &time);
 }
 #endif
@@ -198,18 +199,18 @@ CELIX_UTILS_EXPORT celix_status_t 
celixThreadCondition_waitFor(celix_thread_cond
     return celixThreadCondition_waitUntil(cond, mutex, &abstime);
 }
 
-struct timespec celix_threadCondition_getTime() {
-    return celix_threadCondition_getDelayedTime(0);
+struct timespec celixThreadCondition_getTime() {
+    return celixThreadCondition_getDelayedTime(0);
 }
 
-struct timespec celix_threadCondition_getDelayedTime(double delayInSeconds) {
+struct timespec celixThreadCondition_getDelayedTime(double delayInSeconds) {
 #if __APPLE__
     struct timeval tv;
     struct timespec now;
     gettimeofday(&tv, NULL);
     TIMEVAL_TO_TIMESPEC(&tv, &now);
 #else
-    struct timespec new = celix_gettime(CLOCK_MONOTONIC);
+    struct timespec now = celix_gettime(CLOCK_MONOTONIC);
 #endif
     if (delayInSeconds == 0) {
         return now;

Reply via email to