| ... | ... | @@ -219,17 +219,23 @@ const WindowsEvent = AtomicEvent(struct { |
| 219 | 219 | return SpinEvent.Futex.wait(ptr, expected, timeout); |
| 220 | 220 | }; |
| 221 | 221 | |
| 222 | // NT uses timeouts in units of 100ns with negative value being relative |
| 222 | 223 | var timeout_ptr: ?*windows.LARGE_INTEGER = null; |
| 223 | 224 | var timeout_value: windows.LARGE_INTEGER = undefined; |
| 224 | 225 | if (timeout) |timeout_ns| { |
| 225 | 226 | timeout_ptr = &timeout_value; |
| 226 | | timeout_value = @intCast(windows.LARGE_INTEGER, @divFloor(timeout_ns, time.millisecond)); |
| 227 | timeout_value = -@intCast(windows.LARGE_INTEGER, timeout_ns / 100); |
| 227 | 228 | } |
| 228 | 229 | |
| 229 | | const key = @ptrCast(*const c_void, ptr); |
| 230 | | while (@atomicLoad(u32, ptr, .Acquire) == expected) { |
| 230 | // NtWaitForKeyedEvent doesnt have spurious wake-ups |
| 231 | if (@atomicLoad(u32, ptr, .Acquire) == expected) { |
| 232 | const key = @ptrCast(*const c_void, ptr); |
| 231 | 233 | const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, timeout_ptr); |
| 232 | | assert(rc == 0); |
| 234 | switch (rc) { |
| 235 | 0 => {}, |
| 236 | windows.WAIT_TIMEOUT => return ResetEvent.WaitError.TimedOut, |
| 237 | else => unreachable, |
| 238 | } |
| 233 | 239 | } |
| 234 | 240 | } |
| 235 | 241 | |
| ... | ... | @@ -377,10 +383,13 @@ test "std.ResetEvent" { |
| 377 | 383 | |
| 378 | 384 | // test waiting timeout |
| 379 | 385 | const delay = 100 * time.millisecond; |
| 386 | const error_margin = 50 * time.millisecond; |
| 387 | |
| 380 | 388 | var timer = time.Timer.start() catch unreachable; |
| 381 | 389 | testing.expectError(ResetEvent.WaitError.TimedOut, event.wait(delay)); |
| 382 | 390 | const elapsed = timer.read(); |
| 383 | | testing.expect(elapsed >= delay and elapsed < delay * 2); |
| 391 | testing.expect(elapsed >= delay - error_margin); |
| 392 | testing.expect(elapsed <= delay + error_margin); |
| 384 | 393 | |
| 385 | 394 | // test cross thread signaling |
| 386 | 395 | const Context = struct { |