Fix waiting (#675)

This PR fixes `INFINITE` waiting (`SleepEx`, `WaitForSingleObject`,
etc). Currently `INFINITE` is not infinite but "at this moment" (waiting
point in time == `clock.steady_now()`).
This commit is contained in:
Maurice Heumann
2026-01-02 22:14:02 +01:00
committed by GitHub
5 changed files with 18 additions and 5 deletions

View File

@@ -3,8 +3,14 @@
namespace utils
{
std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(clock& c, const LARGE_INTEGER delay_interval)
std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(clock& c, const LARGE_INTEGER delay_interval,
const LARGE_INTEGER infinite_value)
{
if (delay_interval.QuadPart == infinite_value.QuadPart)
{
return std::chrono::steady_clock::time_point::min();
}
if (delay_interval.QuadPart <= 0)
{
const auto relative_time = -delay_interval.QuadPart;

View File

@@ -102,7 +102,9 @@ namespace utils
}
};
std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(clock& c, LARGE_INTEGER delay_interval);
std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(clock& c, LARGE_INTEGER delay_interval,
LARGE_INTEGER infinite_value = {.LowPart = 0,
.HighPart = -2147483648});
KSYSTEM_TIME convert_to_ksystem_time(const std::chrono::system_clock::time_point& tp);
void convert_to_ksystem_time(volatile KSYSTEM_TIME* dest, const std::chrono::system_clock::time_point& tp);

View File

@@ -1006,7 +1006,8 @@ namespace
std::optional<std::chrono::steady_clock::time_point> timeout{};
if (info.Timeout.QuadPart != std::numeric_limits<int64_t>::max())
{
timeout = utils::convert_delay_interval_to_time_point(win_emu.clock(), info.Timeout);
timeout = utils::convert_delay_interval_to_time_point(win_emu.clock(), info.Timeout,
{.QuadPart = std::numeric_limits<int64_t>::max()});
}
this->delay_ioctrl(c, {}, timeout, timeout_callback);

View File

@@ -109,7 +109,8 @@ class emulator_thread : public ref_counted_object
bool is_await_time_over(utils::clock& clock) const
{
return this->await_time.has_value() && this->await_time.value() < clock.steady_now();
constexpr auto infinite = std::chrono::steady_clock::time_point::min();
return this->await_time.has_value() && this->await_time.value() != infinite && this->await_time.value() < clock.steady_now();
}
bool is_terminated() const;

View File

@@ -403,7 +403,10 @@ namespace syscalls
NTSTATUS handle_NtDelayExecution(const syscall_context& c, const BOOLEAN alertable, const emulator_object<LARGE_INTEGER> delay_interval)
{
auto& t = c.win_emu.current_thread();
t.await_time = utils::convert_delay_interval_to_time_point(c.win_emu.clock(), delay_interval.read());
if (delay_interval.value())
{
t.await_time = utils::convert_delay_interval_to_time_point(c.win_emu.clock(), delay_interval.read());
}
c.win_emu.yield_thread(alertable);
return STATUS_SUCCESS;