zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit a0955990dc2c8df42879e33b308ca177ba2c771a (tree)
parent ef208fee3cf7eb25ae08e1a896eba58b91e56d50
Author: kprotty <kbutcher6200@gmail.com>
Date:   Sat, 23 Nov 2019 15:50:08 -0600

fix ResetEvent windows bugs

Diffstat:
Mlib/std/reset_event.zig | 19++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/std/reset_event.zig b/lib/std/reset_event.zig @@ -219,17 +219,23 @@ const WindowsEvent = AtomicEvent(struct { return SpinEvent.Futex.wait(ptr, expected, timeout); }; + // NT uses timeouts in units of 100ns with negative value being relative var timeout_ptr: ?*windows.LARGE_INTEGER = null; var timeout_value: windows.LARGE_INTEGER = undefined; if (timeout) |timeout_ns| { timeout_ptr = &timeout_value; - timeout_value = @intCast(windows.LARGE_INTEGER, @divFloor(timeout_ns, time.millisecond)); + timeout_value = -@intCast(windows.LARGE_INTEGER, timeout_ns / 100); } - const key = @ptrCast(*const c_void, ptr); - while (@atomicLoad(u32, ptr, .Acquire) == expected) { + // NtWaitForKeyedEvent doesnt have spurious wake-ups + if (@atomicLoad(u32, ptr, .Acquire) == expected) { + const key = @ptrCast(*const c_void, ptr); const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, timeout_ptr); - assert(rc == 0); + switch (rc) { + 0 => {}, + windows.WAIT_TIMEOUT => return ResetEvent.WaitError.TimedOut, + else => unreachable, + } } } @@ -377,10 +383,13 @@ test "std.ResetEvent" { // test waiting timeout const delay = 100 * time.millisecond; + const error_margin = 50 * time.millisecond; + var timer = time.Timer.start() catch unreachable; testing.expectError(ResetEvent.WaitError.TimedOut, event.wait(delay)); const elapsed = timer.read(); - testing.expect(elapsed >= delay and elapsed < delay * 2); + testing.expect(elapsed >= delay - error_margin); + testing.expect(elapsed <= delay + error_margin); // test cross thread signaling const Context = struct {