From af7427675ad11e4c51e56399f315a236ca7b57ea Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 22 Dec 2025 13:36:53 -0500 Subject: cmProcess: compute the timeout when needed When a timeout is updated during runtime (e.g., via `TIMEOUT_AFTER_MATCH`), the actual timeout needs recomputed based on consideration of `StopTimeout` as well. Instead of using `Timeout` directly, add a `GetComputedTimeout` method which also retrieves the timeout reason based on which timeout is selected. --- Source/CTest/cmCTestRunTest.cxx | 14 ++++++++++---- Source/CTest/cmProcess.cxx | 25 ++++++++++++++++++++++--- Source/CTest/cmProcess.h | 7 ++++++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index eff891a..de8651c 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -813,9 +813,6 @@ bool cmCTestRunTest::ForkProcess() if (stop_time != std::chrono::system_clock::time_point()) { cmDuration timeUntilStop = (stop_time - std::chrono::system_clock::now()) % std::chrono::hours(24); - if (timeUntilStop < timeRemaining) { - timeRemaining = timeUntilStop; - } this->TestProcess->SetStopTimeout(timeUntilStop); } @@ -825,7 +822,16 @@ bool cmCTestRunTest::ForkProcess() } if (!timeout || timeRemaining < *timeout) { timeout = timeRemaining; - this->TestProcess->SetTimeoutReason(cmProcess::TimeoutReason::StopTime); + } + + // Inform the test process of its normal timeout + if (timeout) { + this->TestProcess->SetTimeout(*timeout); + } + + // Ask the test process which timeout is in effect. + if (auto ctimeout = this->TestProcess->GetComputedTimeout()) { + timeout = ctimeout->Duration; } if (timeout) { diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 9002d2e..9bf81f8 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -158,9 +158,10 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector* affinity) void cmProcess::StartTimer() { - if (this->Timeout) { - auto msec = - std::chrono::duration_cast(*this->Timeout); + if (auto ctimeout = this->GetComputedTimeout()) { + this->TimeoutReason_ = ctimeout->Reason; + auto msec = std::chrono::duration_cast( + ctimeout->Duration); this->Timer.start(&cmProcess::OnTimeoutCB, static_cast(msec.count()), 0, cm::uv_update_time::no); @@ -374,6 +375,24 @@ cmProcess::State cmProcess::GetProcessStatus() return this->ProcessState; } +cm::optional cmProcess::GetComputedTimeout() const +{ + if (this->StopTimeout && this->Timeout) { + if (*this->StopTimeout < *this->Timeout) { + return ComputedTimeout{ TimeoutReason::StopTime, *this->StopTimeout }; + } + return ComputedTimeout{ TimeoutReason::Normal, *this->Timeout }; + } + if (this->StopTimeout) { + return ComputedTimeout{ TimeoutReason::StopTime, *this->StopTimeout }; + } + if (this->Timeout) { + return ComputedTimeout{ TimeoutReason::Normal, *this->Timeout }; + } + + return cm::nullopt; +} + void cmProcess::ChangeTimeout(cmDuration t) { this->Timeout = t; diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h index d3df8d3..a4704b4 100644 --- a/Source/CTest/cmProcess.h +++ b/Source/CTest/cmProcess.h @@ -49,8 +49,13 @@ public: Normal, StopTime, }; - void SetTimeoutReason(TimeoutReason r) { this->TimeoutReason_ = r; } TimeoutReason GetTimeoutReason() const { return this->TimeoutReason_; } + struct ComputedTimeout + { + TimeoutReason Reason; + cmDuration Duration; + }; + cm::optional GetComputedTimeout() const; enum class State { -- cgit v0.12