From 485ec0884ff81a23ca5460a6d07d4e2c2d6b81cb Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 21 Dec 2020 19:44:16 -0700 Subject: [PATCH] restore std.ResetEvent.isSet functionality --- lib/std/c.zig | 1 + lib/std/reset_event.zig | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/std/c.zig b/lib/std/c.zig index 2ba16b2cfc..9579662151 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -276,6 +276,7 @@ pub extern "c" fn sem_post(sem: *sem_t) c_int; pub extern "c" fn sem_wait(sem: *sem_t) c_int; pub extern "c" fn sem_trywait(sem: *sem_t) c_int; pub extern "c" fn sem_timedwait(sem: *sem_t, abs_timeout: *const timespec) c_int; +pub extern "c" fn sem_getvalue(sem: *sem_t, sval: *c_int) c_int; pub extern "c" fn kqueue() c_int; pub extern "c" fn kevent( diff --git a/lib/std/reset_event.zig b/lib/std/reset_event.zig index 7df797f955..58dc40994d 100644 --- a/lib/std/reset_event.zig +++ b/lib/std/reset_event.zig @@ -34,6 +34,14 @@ pub const ResetEvent = struct { self.os_event.deinit(); } + /// When `wait` would return without blocking, this returns `true`. + /// Note that the value may be immediately invalid upon this function's + /// return, because another thread may call `wait` in between, changing + /// the event's set/cleared status. + pub fn isSet(self: *ResetEvent) bool { + return self.os_event.isSet(); + } + /// Sets the event if not already set and /// wakes up all the threads waiting on the event. pub fn set(self: *ResetEvent) void { @@ -77,6 +85,10 @@ const DebugEvent = struct { self.* = undefined; } + fn isSet(self: *DebugEvent) bool { + return self.is_set; + } + fn reset(self: *DebugEvent) void { self.is_set = false; } @@ -122,6 +134,13 @@ const PosixEvent = struct { self.* = undefined; } + fn isSet(self: *PosixEvent) bool { + const sem = self.getInitializedSem(); + var val: c_int = undefined; + assert(c.sem_getvalue(sem, &val) == 0); + return val > 0; + } + fn reset(self: *PosixEvent) void { const sem = self.getInitializedSem(); while (true) { @@ -208,6 +227,10 @@ const AtomicEvent = struct { self.* = undefined; } + fn isSet(self: *const AtomicEvent) bool { + return @atomicLoad(u32, &self.waiters, .Acquire) == WAKE; + } + fn reset(self: *AtomicEvent) void { @atomicStore(u32, &self.waiters, 0, .Monotonic); } @@ -374,10 +397,13 @@ test "ResetEvent" { defer event.deinit(); // test event setting + testing.expect(!event.isSet()); event.set(); + testing.expect(event.isSet()); // test event resetting event.reset(); + testing.expect(!event.isSet()); // test event waiting (non-blocking) event.set();