diff options
| author | protty <45520026+kprotty@users.noreply.github.com> | 2022-04-26 16:48:56 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-26 16:48:56 -0500 |
| commit | 18f30346291bd2471e07924af161de080935dd60 (patch) | |
| tree | 609cdd73aa40f15625f896e79b9420b3e320ddcd /lib/std/event | |
| parent | 50f1856476038e57f5d2f47c751f608b0b360662 (diff) | |
| download | zig-18f30346291bd2471e07924af161de080935dd60.tar.gz zig-18f30346291bd2471e07924af161de080935dd60.zip | |
std.Thread: ResetEvent improvements (#11523)
* std: start removing redundant ResetEvents
* src: fix other uses of std.Thread.ResetEvent
* src: add builtin.sanitize_thread for tsan detection
* atomic: add Atomic.fence for proper fencing with tsan
* Thread: remove the other ResetEvent's and rewrite the current one
* Thread: ResetEvent docs
* zig fmt + WaitGroup.reset() fix
* src: fix build issues for ResetEvent + tsan
* Thread: ResetEvent tests
* Thread: ResetEvent module doc
* Atomic: replace llvm *p memory constraint with *m
* panicking: handle spurious wakeups in futex.wait() when waiting for abort()
* zig fmt
Diffstat (limited to 'lib/std/event')
| -rw-r--r-- | lib/std/event/loop.zig | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index 1eaa95d249..038ead12b5 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -8,6 +8,7 @@ const os = std.os; const windows = os.windows; const maxInt = std.math.maxInt; const Thread = std.Thread; +const Atomic = std.atomic.Atomic; const is_windows = builtin.os.tag == .windows; @@ -168,11 +169,9 @@ pub const Loop = struct { .fs_end_request = .{ .data = .{ .msg = .end, .finish = .NoAction } }, .fs_queue = std.atomic.Queue(Request).init(), .fs_thread = undefined, - .fs_thread_wakeup = undefined, + .fs_thread_wakeup = .{}, .delay_queue = undefined, }; - try self.fs_thread_wakeup.init(); - errdefer self.fs_thread_wakeup.deinit(); errdefer self.arena.deinit(); // We need at least one of these in case the fs thread wants to use onNextTick @@ -202,7 +201,6 @@ pub const Loop = struct { pub fn deinit(self: *Loop) void { self.deinitOsData(); - self.fs_thread_wakeup.deinit(); self.arena.deinit(); self.* = undefined; } @@ -723,9 +721,7 @@ pub const Loop = struct { extra_thread.join(); } - @atomicStore(bool, &self.delay_queue.is_running, false, .SeqCst); - self.delay_queue.event.set(); - self.delay_queue.thread.join(); + self.delay_queue.deinit(); } /// Runs the provided function asynchronously. The function's frame is allocated @@ -851,8 +847,8 @@ pub const Loop = struct { timer: std.time.Timer, waiters: Waiters, thread: std.Thread, - event: std.Thread.AutoResetEvent, - is_running: bool, + event: std.Thread.ResetEvent, + is_running: Atomic(bool), /// Initialize the delay queue by spawning the timer thread /// and starting any timer resources. @@ -862,11 +858,19 @@ pub const Loop = struct { .waiters = DelayQueue.Waiters{ .entries = std.atomic.Queue(anyframe).init(), }, - .event = std.Thread.AutoResetEvent{}, - .is_running = true, - // Must be last so that it can read the other state, such as `is_running`. - .thread = try std.Thread.spawn(.{}, DelayQueue.run, .{self}), + .thread = undefined, + .event = .{}, + .is_running = Atomic(bool).init(true), }; + + // Must be after init so that it can read the other state, such as `is_running`. + self.thread = try std.Thread.spawn(.{}, DelayQueue.run, .{self}); + } + + fn deinit(self: *DelayQueue) void { + self.is_running.store(false, .SeqCst); + self.event.set(); + self.thread.join(); } /// Entry point for the timer thread @@ -874,7 +878,8 @@ pub const Loop = struct { fn run(self: *DelayQueue) void { const loop = @fieldParentPtr(Loop, "delay_queue", self); - while (@atomicLoad(bool, &self.is_running, .SeqCst)) { + while (self.is_running.load(.SeqCst)) { + self.event.reset(); const now = self.timer.read(); if (self.waiters.popExpired(now)) |entry| { |
