@@ -39,19 +39,22 @@ class DarwinLoop final : public Loop {
3939
4040 ~DarwinLoop () override { this ->close_fds (); }
4141
42- WakeReason wait (x::breaker::Breaker &breaker) override {
42+ WakeReason wait (
43+ x::breaker::Breaker &breaker,
44+ x::telem::TimeSpan max_timeout = x::telem::TimeSpan(0 )
45+ ) override {
4346 if (this ->kqueue_fd_ == -1 ) return WakeReason::Shutdown;
4447
4548 switch (this ->config_ .mode ) {
4649 case ExecutionMode::AUTO:
4750 case ExecutionMode::EVENT_DRIVEN:
48- return this ->event_driven_wait ();
51+ return this ->event_driven_wait (max_timeout );
4952 case ExecutionMode::BUSY_WAIT:
5053 return this ->busy_wait (breaker);
5154 case ExecutionMode::HIGH_RATE:
5255 return this ->high_rate_wait (breaker);
5356 case ExecutionMode::HYBRID:
54- return this ->hybrid_wait (breaker);
57+ return this ->hybrid_wait (breaker, max_timeout );
5558 case ExecutionMode::RT_EVENT:
5659 return this ->high_rate_wait (breaker);
5760 }
@@ -195,7 +198,10 @@ class DarwinLoop final : public Loop {
195198 }
196199
197200 // / @brief HYBRID: Spin for configured duration, then block with timeout.
198- WakeReason hybrid_wait (const x::breaker::Breaker &breaker) const {
201+ WakeReason hybrid_wait (
202+ const x::breaker::Breaker &breaker,
203+ const x::telem::TimeSpan max_timeout
204+ ) const {
199205 const auto spin_start = std::chrono::steady_clock::now ();
200206 const auto spin_duration = this ->config_ .spin_duration .chrono ();
201207 struct timespec timeout = {0 , 0 };
@@ -205,18 +211,22 @@ class DarwinLoop final : public Loop {
205211 const int n = kevent (this ->kqueue_fd_ , nullptr , 0 , events, 8 , &timeout);
206212 if (n > 0 ) return this ->classify_events (events, n);
207213 }
208- const auto block_timeout_ns = timing::HYBRID_BLOCK_TIMEOUT.nanoseconds ();
209- timeout.tv_sec = 0 ;
210- timeout.tv_nsec = block_timeout_ns;
214+ const auto block_ns = max_timeout.nanoseconds () > 0
215+ ? max_timeout.nanoseconds ()
216+ : timing::HYBRID_BLOCK_TIMEOUT.nanoseconds ();
217+ timeout = ns_to_timespec (block_ns);
211218 const int n = kevent (this ->kqueue_fd_ , nullptr , 0 , events, 8 , &timeout);
212219 if (n > 0 ) return this ->classify_events (events, n);
213220 return WakeReason::Timeout;
214221 }
215222
216223 // / @brief EVENT_DRIVEN: Block on kqueue events with timeout.
217- WakeReason event_driven_wait () const {
224+ WakeReason event_driven_wait (const x::telem::TimeSpan max_timeout ) const {
218225 struct kevent events[8 ];
219- const struct timespec timeout = {0 , timing::EVENT_DRIVEN_TIMEOUT.nanoseconds ()};
226+ const auto timeout_ns = max_timeout.nanoseconds () > 0
227+ ? max_timeout.nanoseconds ()
228+ : timing::EVENT_DRIVEN_TIMEOUT.nanoseconds ();
229+ const auto timeout = ns_to_timespec (timeout_ns);
220230 const int n = kevent (this ->kqueue_fd_ , nullptr , 0 , events, 8 , &timeout);
221231
222232 if (n > 0 ) return this ->classify_events (events, n);
@@ -237,6 +247,10 @@ class DarwinLoop final : public Loop {
237247 return WakeReason::Shutdown;
238248 }
239249
250+ static constexpr timespec ns_to_timespec (const int64_t ns) {
251+ return {ns / 1'000'000'000 , ns % 1'000'000'000 };
252+ }
253+
240254 Config config_;
241255 int kqueue_fd_ = -1 ;
242256 bool kqueue_timer_enabled_ = false ;
0 commit comments