Commit 4eb4d26fa1
lib/std/c.zig
@@ -316,6 +316,7 @@ pub extern "c" fn dn_expand(
pub const PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{};
pub extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) c_int;
pub extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) c_int;
+pub extern "c" fn pthread_mutex_trylock(mutex: *pthread_mutex_t) c_int;
pub extern "c" fn pthread_mutex_destroy(mutex: *pthread_mutex_t) c_int;
pub const PTHREAD_COND_INITIALIZER = pthread_cond_t{};
lib/std/mutex.zig
@@ -37,6 +37,8 @@ pub const Mutex = if (builtin.single_threaded)
Dummy
else if (builtin.os.tag == .windows)
WindowsMutex
+else if (std.Thread.use_pthreads)
+ PthreadMutex
else if (builtin.link_libc or builtin.os.tag == .linux)
// stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs
struct {
@@ -166,6 +168,52 @@ else if (builtin.link_libc or builtin.os.tag == .linux)
else
SpinLock;
+pub const PthreadMutex = struct {
+ pthread_mutex: std.c.pthread_mutex_t = init,
+
+ pub const Held = struct {
+ mutex: *PthreadMutex,
+
+ pub fn release(self: Held) void {
+ switch (std.c.pthread_mutex_unlock(&self.mutex.pthread_mutex)) {
+ 0 => return,
+ std.c.EINVAL => unreachable,
+ std.c.EAGAIN => unreachable,
+ std.c.EPERM => unreachable,
+ else => unreachable,
+ }
+ }
+ };
+
+ /// Create a new mutex in unlocked state.
+ pub const init = std.c.PTHREAD_MUTEX_INITIALIZER;
+
+ /// Try to acquire the mutex without blocking. Returns null if
+ /// the mutex is unavailable. Otherwise returns Held. Call
+ /// release on Held.
+ pub fn tryAcquire(self: *PthreadMutex) ?Held {
+ if (std.c.pthread_mutex_trylock(&self.pthread_mutex) == 0) {
+ return Held{ .mutex = self };
+ } else {
+ return null;
+ }
+ }
+
+ /// Acquire the mutex. Will deadlock if the mutex is already
+ /// held by the calling thread.
+ pub fn acquire(self: *PthreadMutex) Held {
+ switch (std.c.pthread_mutex_lock(&self.pthread_mutex)) {
+ 0 => return Held{ .mutex = self },
+ std.c.EINVAL => unreachable,
+ std.c.EBUSY => unreachable,
+ std.c.EAGAIN => unreachable,
+ std.c.EDEADLK => unreachable,
+ std.c.EPERM => unreachable,
+ else => unreachable,
+ }
+ }
+};
+
/// This has the sematics as `Mutex`, however it does not actually do any
/// synchronization. Operations are safety-checked no-ops.
pub const Dummy = struct {