| ... | ... | @@ -62,57 +62,50 @@ pub const Mutex = switch(builtin.os) { |
| 62 | 62 | }, |
| 63 | 63 | builtin.Os.windows => struct { |
| 64 | 64 | |
| 65 | | lock: ?windows.CRITICAL_SECTION, |
| 66 | | init_once: windows.PINIT_ONCE, |
| 65 | lock: windows.CRITICAL_SECTION, |
| 66 | init_once: windows.RTL_RUN_ONCE, |
| 67 | 67 | |
| 68 | 68 | pub const Held = struct { |
| 69 | 69 | mutex: *Mutex, |
| 70 | 70 | |
| 71 | 71 | pub fn release(self: Held) void { |
| 72 | | if (self.mutex.lock) |*lock| { |
| 73 | | windows.LeaveCriticalSection(lock); |
| 74 | | } |
| 72 | windows.LeaveCriticalSection(&self.mutex.lock); |
| 75 | 73 | } |
| 76 | 74 | }; |
| 77 | 75 | |
| 78 | 76 | pub fn init() Mutex { |
| 79 | | return Mutex { |
| 80 | | .lock = null, |
| 77 | return Mutex { |
| 78 | .lock = undefined, |
| 81 | 79 | .init_once = undefined, |
| 82 | 80 | }; |
| 83 | 81 | } |
| 84 | 82 | |
| 85 | | extern fn initCriticalSection(InitOnce: *windows.PINIT_ONCE, Parameter: ?windows.PVOID, Context: ?windows.PVOID) windows.BOOL { |
| 86 | | if (Context) |ctx| { |
| 87 | | var mutex = @ptrCast(*?windows.CRITICAL_SECTION, @alignCast(8, ctx)); |
| 88 | | if (mutex.* == null) { |
| 89 | | var lock: windows.CRITICAL_SECTION = undefined; |
| 90 | | windows.InitializeCriticalSection(&lock); |
| 91 | | mutex.* = lock; |
| 92 | | } |
| 93 | | return windows.TRUE; |
| 94 | | } |
| 95 | | return windows.FALSE; |
| 83 | extern fn initCriticalSection( |
| 84 | InitOnce: *windows.RTL_RUN_ONCE, |
| 85 | Parameter: ?windows.PVOID, |
| 86 | Context: ?windows.PVOID |
| 87 | ) windows.BOOL { |
| 88 | var lock = @ptrCast( |
| 89 | *windows.CRITICAL_SECTION, |
| 90 | @alignCast(@alignOf(*windows.CRITICAL_SECTION), ctx.?) |
| 91 | ); |
| 92 | windows.InitializeCriticalSection(lock); |
| 93 | return windows.TRUE; |
| 96 | 94 | } |
| 97 | 95 | |
| 98 | 96 | pub fn deinit(self: *Mutex) void { |
| 99 | | if (self.lock) |*lock| { |
| 100 | | windows.DeleteCriticalSection(lock); |
| 101 | | } |
| 97 | windows.DeleteCriticalSection(&self.lock); |
| 102 | 98 | } |
| 103 | 99 | |
| 104 | 100 | pub fn acquire(self: *Mutex) Held { |
| 105 | | if (self.lock) |*lock| { |
| 106 | | windows.EnterCriticalSection(lock); |
| 107 | | } else { |
| 108 | | var mutex = @ptrCast(?windows.PVOID, self); |
| 109 | | if (windows.InitOnceExecuteOnce(&self.init_once, initCriticalSection, null, mutex) == windows.TRUE) { |
| 110 | | windows.EnterCriticalSection(&self.lock.?); |
| 111 | | } else { |
| 112 | | @panic("unable to initialize Mutex"); |
| 113 | | } |
| 101 | if (windows.InitOnceExecuteOnce( |
| 102 | &self.init_once, |
| 103 | initCriticalSection, |
| 104 | null, @ptrCast(?windows.PVOID, self) |
| 105 | ) == windows.FALSE) { |
| 106 | unreachable; |
| 114 | 107 | } |
| 115 | | |
| 108 | windows.EnterCriticalSection(&self.lock); |
| 116 | 109 | return Held { .mutex = self }; |
| 117 | 110 | } |
| 118 | 111 | }, |