diff --git a/src/system/SystemLayerImplSelect.cpp b/src/system/SystemLayerImplSelect.cpp index 9eb0b2ece2864b..7ae25a0a59d134 100644 --- a/src/system/SystemLayerImplSelect.cpp +++ b/src/system/SystemLayerImplSelect.cpp @@ -66,8 +66,10 @@ CHIP_ERROR LayerImplSelect::Init() mHandleSelectThread = PTHREAD_NULL; #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING +#if !CHIP_SYSTEM_CONFIG_USE_LIBEV // Create an event to allow an arbitrary thread to wake the thread in the select loop. ReturnErrorOnFailure(mWakeEvent.Open(*this)); +#endif // !CHIP_SYSTEM_CONFIG_USE_LIBEV VerifyOrReturnError(mLayerState.SetInitialized(), CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; @@ -113,13 +115,18 @@ void LayerImplSelect::Shutdown() mTimerPool.ReleaseAll(); #endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH/LIBEV +#if !CHIP_SYSTEM_CONFIG_USE_LIBEV mWakeEvent.Close(*this); +#endif // !CHIP_SYSTEM_CONFIG_USE_LIBEV mLayerState.ResetFromShuttingDown(); // Return to uninitialized state to permit re-initialization. } void LayerImplSelect::Signal() { +#if CHIP_SYSTEM_CONFIG_USE_LIBEV + ChipLogError(DeviceLayer, "Signal() should not be called in CHIP_SYSTEM_CONFIG_USE_LIBEV builds (might be ok in tests)"); +#else /* * Wake up the I/O thread by writing a single byte to the wake pipe. * @@ -143,6 +150,7 @@ void LayerImplSelect::Signal() ChipLogError(chipSystemLayer, "System wake event notify failed: %" CHIP_ERROR_FORMAT, status.Format()); } +#endif // !CHIP_SYSTEM_CONFIG_USE_LIBEV } CHIP_ERROR LayerImplSelect::StartTimer(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState) @@ -184,7 +192,14 @@ CHIP_ERROR LayerImplSelect::StartTimer(Clock::Timeout delay, TimerCompleteCallba ev_timer_init(&timer->mLibEvTimer, &LayerImplSelect::HandleLibEvTimer, 1, 0); timer->mLibEvTimer.data = timer; auto t = Clock::Milliseconds64(delay).count(); - ev_timer_set(&timer->mLibEvTimer, static_cast(t) / 1E3, 0.); + // Note: libev uses the time when events started processing as the "now" reference for relative timers, + // for efficiency reasons. This point in time is represented by ev_now(). + // The real time is represented by ev_time(). + // Without correction, this leads to timers firing a bit too early relative to the time StartTimer() + // is called. So the relative value passed to ev_timer_set() is adjusted (increased) here. + // Note: Still, slightly early (and of course, late) firing timers are something the caller MUST be prepared for, + // because edge cases like system clock adjustments may cause them even with the correction applied here. + ev_timer_set(&timer->mLibEvTimer, (static_cast(t) / 1E3) + ev_time() - ev_now(mLibEvLoopP), 0.); (void) mTimerList.Add(timer); ev_timer_start(mLibEvLoopP, &timer->mLibEvTimer); return CHIP_NO_ERROR; @@ -269,7 +284,10 @@ void LayerImplSelect::CancelTimer(TimerCompleteCallback onComplete, void * appSt #endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH/LIBEV mTimerPool.Release(timer); +#if !CHIP_SYSTEM_CONFIG_USE_LIBEV + // LIBEV has no I/O wakeup thread, so must not call Signal() Signal(); +#endif } CHIP_ERROR LayerImplSelect::ScheduleWork(TimerCompleteCallback onComplete, void * appState) diff --git a/src/system/SystemLayerImplSelect.h b/src/system/SystemLayerImplSelect.h index c835b8a76720c5..361feef991460f 100644 --- a/src/system/SystemLayerImplSelect.h +++ b/src/system/SystemLayerImplSelect.h @@ -146,7 +146,9 @@ class LayerImplSelect : public LayerSocketsLoop int mSelectResult; ObjectLifeCycle mLayerState; +#if !CHIP_SYSTEM_CONFIG_USE_LIBEV WakeEvent mWakeEvent; +#endif #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING std::atomic mHandleSelectThread; diff --git a/src/system/WakeEvent.cpp b/src/system/WakeEvent.cpp index 4b5d7c2a9ad00f..12ed9231e4a2de 100644 --- a/src/system/WakeEvent.cpp +++ b/src/system/WakeEvent.cpp @@ -23,7 +23,7 @@ #include -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS +#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && !CHIP_SYSTEM_CONFIG_USE_LIBEV #include @@ -207,4 +207,4 @@ CHIP_ERROR WakeEvent::Notify() const } // namespace System } // namespace chip -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS +#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && !CHIP_SYSTEM_CONFIG_USE_LIBEV diff --git a/src/system/WakeEvent.h b/src/system/WakeEvent.h index b979c67ab17752..d0c603952c21b7 100644 --- a/src/system/WakeEvent.h +++ b/src/system/WakeEvent.h @@ -25,7 +25,7 @@ // Include configuration headers #include -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS +#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && !CHIP_SYSTEM_CONFIG_USE_LIBEV #include #include @@ -67,4 +67,4 @@ class WakeEvent } // namespace System } // namespace chip -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS +#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && !CHIP_SYSTEM_CONFIG_USE_LIBEV