zig/src/WaitGroup.zig
Andrew Kelley 008b0ec5e5 std.Thread.Mutex: change API to lock() and unlock()
This is a breaking change. Before, usage looked like this:

```zig
const held = mutex.acquire();
defer held.release();
```

Now it looks like this:

```zig
mutex.lock();
defer mutex.unlock();
```

The `Held` type was an idea to make mutexes slightly safer by making it
more difficult to forget to release an aquired lock. However, this
ultimately caused more problems than it solved, when any data structures
needed to store a held mutex. Simplify everything by reducing the API
down to the primitives: lock() and unlock().

Closes #8051
Closes #8246
Closes #10105
2021-11-09 18:31:03 -07:00

62 lines
1.2 KiB
Zig

// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2020 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("std");
const WaitGroup = @This();
mutex: std.Thread.Mutex = .{},
counter: usize = 0,
event: std.Thread.ResetEvent,
pub fn init(self: *WaitGroup) !void {
self.* = .{
.mutex = .{},
.counter = 0,
.event = undefined,
};
try self.event.init();
}
pub fn deinit(self: *WaitGroup) void {
self.event.deinit();
self.* = undefined;
}
pub fn start(self: *WaitGroup) void {
self.mutex.lock();
defer self.mutex.unlock();
self.counter += 1;
}
pub fn finish(self: *WaitGroup) void {
self.mutex.lock();
defer self.mutex.unlock();
self.counter -= 1;
if (self.counter == 0) {
self.event.set();
}
}
pub fn wait(self: *WaitGroup) void {
while (true) {
self.mutex.lock();
if (self.counter == 0) {
self.mutex.unlock();
return;
}
self.mutex.unlock();
self.event.wait();
}
}
pub fn reset(self: *WaitGroup) void {
self.event.reset();
}