diff options
| author | Frank Denis <github@pureftpd.org> | 2024-03-18 00:39:32 +0100 |
|---|---|---|
| committer | Frank Denis <github@pureftpd.org> | 2024-03-18 16:51:41 +0100 |
| commit | c470016743474cd4686ddb523652b4ad7c7ef42f (patch) | |
| tree | edff409066bf71d0d375c04c6d0382a32c627924 /lib/std/Thread.zig | |
| parent | 8e7d9afdacef9d3a9443fc4b70cfe6aa229ecee5 (diff) | |
| download | zig-c470016743474cd4686ddb523652b4ad7c7ef42f.tar.gz zig-c470016743474cd4686ddb523652b4ad7c7ef42f.zip | |
Unbreak support for WASI threads
Diffstat (limited to 'lib/std/Thread.zig')
| -rw-r--r-- | lib/std/Thread.zig | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index e895183331..6866a1702d 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -324,6 +324,9 @@ pub const SpawnError = error{ /// would exceed the limit. LockedMemoryLimitExceeded, + /// An allocator is required to spawn a thread + AllocatorRequired, + Unexpected, }; @@ -819,7 +822,7 @@ const WasiThreadImpl = struct { \\ memory.atomic.wait32 0 \\ local.set %[ret] : [ret] "=r" (-> u32), - : [ptr] "r" (&self.thread.tid.value), + : [ptr] "r" (&self.thread.tid.raw), [expected] "r" (tid), ); switch (result) { @@ -831,15 +834,42 @@ const WasiThreadImpl = struct { } } - fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) !WasiThreadImpl { - if (config.allocator == null) return error.OutOfMemory; // an allocator is required to spawn a WASI-thread + fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) SpawnError!WasiThreadImpl { + if (config.allocator == null) { + return error.AllocatorRequired; // an allocator is required to spawn a WASI thread + } // Wrapping struct required to hold the user-provided function arguments. const Wrapper = struct { args: @TypeOf(args), fn entry(ptr: usize) void { const w: *@This() = @ptrFromInt(ptr); - @call(.auto, f, w.args); + const bad_fn_ret = "expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"; + switch (@typeInfo(@typeInfo(@TypeOf(f)).Fn.return_type.?)) { + .NoReturn, .Void => { + @call(.auto, w, args); + }, + .Int => |info| { + if (info.bits != 8) { + @compileError(bad_fn_ret); + } + _ = @call(.auto, w, args); // WASI threads don't support exit status, ignore value + }, + .ErrorUnion => |info| { + if (info.payload != void) { + @compileError(bad_fn_ret); + } + @call(.auto, f, args) catch |err| { + std.debug.print("error: {s}\n", .{@errorName(err)}); + if (@errorReturnTrace()) |trace| { + std.debug.dumpStackTrace(trace.*); + } + }; + }, + else => { + @compileError(bad_fn_ret); + }, + } } }; @@ -927,7 +957,7 @@ const WasiThreadImpl = struct { \\ i32.const 0 \\ i32.atomic.store 0 : - : [ptr] "r" (&arg.thread.tid.value), + : [ptr] "r" (&arg.thread.tid.raw), ); // Wake the main thread listening to this thread @@ -937,7 +967,7 @@ const WasiThreadImpl = struct { \\ memory.atomic.notify 0 \\ drop # no need to know the waiters : - : [ptr] "r" (&arg.thread.tid.value), + : [ptr] "r" (&arg.thread.tid.raw), ); }, .completed => unreachable, |
