authorgravatar for kbutcher6200@gmail.comkprotty <kbutcher6200@gmail.com> 2019-11-23 15:50:08-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-26 20:40:04-05:00
loga0955990dc2c8df42879e33b308ca177ba2c771a
tree672e55c1a71f068aafbc987aea9b639e590b5929
parentef208fee3cf7eb25ae08e1a896eba58b91e56d50
signaturelock-open Commit is signed but in an unrecognized format.

fix ResetEvent windows bugs


1 files changed, 14 insertions(+), 5 deletions(-)

lib/std/reset_event.zig+14-5
......@@ -219,17 +219,23 @@ const WindowsEvent = AtomicEvent(struct {
219219 return SpinEvent.Futex.wait(ptr, expected, timeout);
220220 };
221221
222 // NT uses timeouts in units of 100ns with negative value being relative
222223 var timeout_ptr: ?*windows.LARGE_INTEGER = null;
223224 var timeout_value: windows.LARGE_INTEGER = undefined;
224225 if (timeout) |timeout_ns| {
225226 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);
227228 }
228229
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);
231233 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 }
233239 }
234240 }
235241
......@@ -377,10 +383,13 @@ test "std.ResetEvent" {
377383
378384 // test waiting timeout
379385 const delay = 100 * time.millisecond;
386 const error_margin = 50 * time.millisecond;
387
380388 var timer = time.Timer.start() catch unreachable;
381389 testing.expectError(ResetEvent.WaitError.TimedOut, event.wait(delay));
382390 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);
384393
385394 // test cross thread signaling
386395 const Context = struct {