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;
