From 44e5319107f5d5f7b5bd4cc9917b038196999857 Mon Sep 17 00:00:00 2001 From: Giuseppe Cesarano Date: Sat, 10 Oct 2026 19:11:35 +0200 Subject: [PATCH] Remove extern from Io.Mutex (#37081) An `Io.Mutex` is bound to the Io implementation used to lock and unlock it: having it cross Io implementations could already be an abuse of the API. C code is even further removed, since it has no `Io` at all and could never meaningfully interact with an `Io.Mutex`, so making it `extern` doesn't buy us anything. The only thing we actually gain is less boilerplate when the user needs to protect a struct that is also used from C, where the C side doesn't need the synchronization. I would argue that's not a strong enough reason to keep it `extern`, since the same behavior can be achieved with composition. Being `extern` also conflicts with adding safety features to the implementation: their size would change with the compilation configuration, which defeats the purpose of `extern`. Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37081 Reviewed-by: Andrew Kelley --- lib/std/Io.zig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 9bd7ec5a0dc76ed8628b7a9933b7c1bf41203ec3..3924d8ca00f44db50cec2301add1fedf7573195c 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -1740,9 +1740,11 @@ pub fn futexWake(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, m /// Mutex is a synchronization primitive which enforces atomic access to a /// shared region of code known as the "critical section". /// -/// Mutex is an extern struct so that it may be used as a field inside another -/// extern struct. -pub const Mutex = extern struct { +/// Mutex is not an extern struct because locking and unlocking go through the +/// futex calls of `Io`, which are not required to work across processes or +/// compilation units. Code that needs a fixed layout can build its own lock on +/// a `u32` with the same futex calls. +pub const Mutex = struct { state: std.atomic.Value(State), pub const init: Mutex = .{ .state = .init(.unlocked) }; -- 2.54.0