Commit 485ec0884f

Andrew Kelley <andrew@ziglang.org>
2020-12-22 03:44:16
restore std.ResetEvent.isSet functionality
1 parent a368c0d
Changed files (2)
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(
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();