From c7acf52ab1d802b3f466a32fa527a27933776a7b Mon Sep 17 00:00:00 2001 From: "staging-devin-ai-integration[bot]" <166158716+staging-devin-ai-integration[bot]@users.noreply.github.com> Date: Sat, 7 Dec 2024 04:13:52 +0000 Subject: [PATCH] Fix stepEventLoop timeout handling - Respect user-provided timeout when timers exist - Exit loop when epoll_wait times out with no events/timers Fixes morganstanley/hobbes#436 --- lib/hobbes/events/events.C | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/hobbes/events/events.C b/lib/hobbes/events/events.C index 4faa80b7..e944c31f 100644 --- a/lib/hobbes/events/events.C +++ b/lib/hobbes/events/events.C @@ -1,4 +1,3 @@ - #include #include #include @@ -92,17 +91,21 @@ void registerInterruptHandler(const std::function& fn) { } bool stepEventLoop(int timeoutMS, const std::function& stopFn) { + bool status = true; while (!stopFn()) { if (!timers.empty()) { auto next = timers.top().callTime; auto timeUntilNext = next - std::chrono::high_resolution_clock::now(); int millis = std::chrono::duration_cast(timeUntilNext).count(); - timeoutMS = std::max(1, millis); + if (timeoutMS == -1) { + timeoutMS = std::max(1, millis); + } else { + timeoutMS = std::min(timeoutMS, std::max(1, millis)); + } } struct epoll_event evts[64]; int fds = epoll_wait(threadEPollFD(), evts, sizeof(evts)/sizeof(evts[0]), timeoutMS); - bool status = true; if (fds > 0) { for (int fd = 0; fd < fds; ++fd) { auto* c = reinterpret_cast(evts[fd].data.ptr); @@ -112,6 +115,7 @@ bool stepEventLoop(int timeoutMS, const std::function& stopFn) { } else if (fds < 0) { if (errno != EINTR) { status = false; + break; } else if (epClosures != nullptr) { auto f = epClosures->find(-1); if (f != epClosures->end()) { @@ -142,10 +146,12 @@ bool stepEventLoop(int timeoutMS, const std::function& stopFn) { for (auto& timer : newTimers) { timers.push(timer); } + } else { + // No events and no timers, break on timeout + break; } - return status; } - return false; + return status; } void runEventLoop(const std::function& stopFn) {