Commit 43900011f7

kprotty <kbutcher6200@gmail.com>
2019-11-08 01:56:43
handle NtCreateKeyedEvent failure by spinning to ensure correctness
1 parent fe8c1cf
Changed files (1)
lib
lib/std/parker.zig
@@ -1,5 +1,6 @@
 const std = @import("std.zig");
 const builtin = @import("builtin");
+const time = std.time;
 const testing = std.testing;
 const assert = std.debug.assert;
 const SpinLock = std.SpinLock;
@@ -76,12 +77,13 @@ const WindowsParker = struct {
     pub fn deinit(self: *WindowsParker) void {}
 
     pub fn unpark(self: *WindowsParker, ptr: *const u32) void {
-        const handle = getEventHandlePtr().*;
         const key = @ptrCast(*const c_void, ptr);
+        const handle_ptr = getEventHandlePtr() orelse return;
+
         var waiting = @atomicLoad(u32, &self.waiters, .Monotonic);
         while (waiting != 0) {
             waiting = @cmpxchgWeak(u32, &self.waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
-                const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
+                const rc = windows.ntdll.NtReleaseKeyedEvent(handle_ptr.*, key, windows.FALSE, null);
                 assert(rc == 0);
                 return;
             };
@@ -89,22 +91,27 @@ const WindowsParker = struct {
     }
 
     pub fn park(self: *WindowsParker, ptr: *const u32, expected: u32) void {
-        const handle = getEventHandlePtr().*;
+        var spin = SpinLock.Backoff.init();
         const key = @ptrCast(*const c_void, ptr);
+        
         while (@atomicLoad(u32, ptr, .Acquire) == expected) {
-            _ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
-            const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
-            assert(rc == 0);
+            if (getEventHandlePtr()) |handle_ptr| {
+                _ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
+                const rc = windows.ntdll.NtWaitForKeyedEvent(handle_ptr.*, key, windows.FALSE, null);
+                assert(rc == 0);
+            } else {
+                spin.yield();
+            }
         }
     }
 
     var event_handle = std.lazyInit(windows.HANDLE);
 
-    fn getEventHandlePtr() *const windows.HANDLE {
+    fn getEventHandlePtr() ?*const windows.HANDLE {
         return event_handle.get() orelse {
             const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
             if (windows.ntdll.NtCreateKeyedEvent(&event_handle.data, access_mask, null, 0) != 0)
-                @panic("Failed to setup an NT Keyed Event handle for the process");
+                return null;
             event_handle.resolve();
             return &event_handle.data;
         };