From 9a43cea14ed274705f5ff65b55bba9117b2fe1c3 Mon Sep 17 00:00:00 2001 From: "andrey.bychkov" Date: Thu, 6 Aug 2026 10:19:02 +0300 Subject: [PATCH] fix(PIConditionVariable): clamp negative timeout in waitFor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When elapsed time exceeded the timeout, the remaining milliseconds expression went negative and was implicitly converted to DWORD, wrapping to ~0xFFFFFFFF (5 days) — effectively INFINITE. Now clamps to 0 and returns false when time has elapsed. --- libs/main/thread/piconditionvar.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index 753b2cfc..d32dc3a4 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -135,17 +135,19 @@ bool PIConditionVariable::waitFor(PIMutex & lk, PISystemTime timeout, std::funct if (condition()) break; bool isTimeout; #if defined(WINDOWS) - isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, - (PCRITICAL_SECTION)lk.handle(), - timeout.toMilliseconds() - (int)measurer.elapsed_m()) == 0; + { + int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m()); + if (remain <= 0) return false; + isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), remain) == 0; + } #elif defined(FREERTOS) - EventBits_t uxBits; - uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, - 1, - pdTRUE, - pdTRUE, - (timeout.toMilliseconds() - (int)measurer.elapsed_m()) / portTICK_PERIOD_MS); - isTimeout = (uxBits & 1) == 0; + { + int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m()); + if (remain <= 0) return false; + EventBits_t uxBits; + uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, remain / portTICK_PERIOD_MS); + isTimeout = (uxBits & 1) == 0; + } #else isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t *)lk.handle(), &expire_ts) != 0; #endif