authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-19 20:15:50-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:11-08:00
log77d2ad8c929680ed35fcfe6646f940518a07e7e4
treef07cbefcc9b20049369188bfac27734a3c37c655
parent50c585227ed2a57a4c1cf3f3b44914881999559d

std: consolidate all instances of std.Io.Threaded into a singleton

It's better to avoid references to this global variable, but, in the cases where it's needed, such as in std.debug.print and collecting stack traces, better to share the same instance.

20 files changed, 56 insertions(+), 53 deletions(-)

lib/compiler/test_runner.zig+5-5
...@@ -17,7 +17,7 @@ var fba: std.heap.FixedBufferAllocator = .init(&fba_buffer);...@@ -17,7 +17,7 @@ var fba: std.heap.FixedBufferAllocator = .init(&fba_buffer);
17var fba_buffer: [8192]u8 = undefined;17var fba_buffer: [8192]u8 = undefined;
18var stdin_buffer: [4096]u8 = undefined;18var stdin_buffer: [4096]u8 = undefined;
19var stdout_buffer: [4096]u8 = undefined;19var stdout_buffer: [4096]u8 = undefined;
20var runner_threaded_io: Io.Threaded = .init_single_threaded;20const runner_threaded_io: Io = Io.Threaded.global_single_threaded.ioBasic();
2121
22/// Keep in sync with logic in `std.Build.addRunArtifact` which decides whether22/// Keep in sync with logic in `std.Build.addRunArtifact` which decides whether
23/// the test runner will communicate with the build runner via `std.zig.Server`.23/// the test runner will communicate with the build runner via `std.zig.Server`.
...@@ -74,8 +74,8 @@ pub fn main() void {...@@ -74,8 +74,8 @@ pub fn main() void {
7474
75fn mainServer() !void {75fn mainServer() !void {
76 @disableInstrumentation();76 @disableInstrumentation();
77 var stdin_reader = Io.File.stdin().readerStreaming(runner_threaded_io.io(), &stdin_buffer);77 var stdin_reader = Io.File.stdin().readerStreaming(runner_threaded_io, &stdin_buffer);
78 var stdout_writer = Io.File.stdout().writerStreaming(runner_threaded_io.io(), &stdout_buffer);78 var stdout_writer = Io.File.stdout().writerStreaming(runner_threaded_io, &stdout_buffer);
79 var server = try std.zig.Server.init(.{79 var server = try std.zig.Server.init(.{
80 .in = &stdin_reader.interface,80 .in = &stdin_reader.interface,
81 .out = &stdout_writer.interface,81 .out = &stdout_writer.interface,
...@@ -224,11 +224,11 @@ fn mainTerminal() void {...@@ -224,11 +224,11 @@ fn mainTerminal() void {
224 var skip_count: usize = 0;224 var skip_count: usize = 0;
225 var fail_count: usize = 0;225 var fail_count: usize = 0;
226 var fuzz_count: usize = 0;226 var fuzz_count: usize = 0;
227 const root_node = if (builtin.fuzz) std.Progress.Node.none else std.Progress.start(runner_threaded_io.io(), .{227 const root_node = if (builtin.fuzz) std.Progress.Node.none else std.Progress.start(runner_threaded_io, .{
228 .root_name = "Test",228 .root_name = "Test",
229 .estimated_total_items = test_fn_list.len,229 .estimated_total_items = test_fn_list.len,
230 });230 });
231 const have_tty = Io.File.stderr().isTty(runner_threaded_io.io()) catch unreachable;231 const have_tty = Io.File.stderr().isTty(runner_threaded_io) catch unreachable;
232232
233 var leaks: usize = 0;233 var leaks: usize = 0;
234 for (test_fn_list, 0..) |test_fn, i| {234 for (test_fn_list, 0..) |test_fn, i| {
lib/std/Io/Threaded.zig+13
...@@ -626,6 +626,19 @@ pub const init_single_threaded: Threaded = .{...@@ -626,6 +626,19 @@ pub const init_single_threaded: Threaded = .{
626 },626 },
627};627};
628628
629var global_single_threaded_instance: Threaded = .init_single_threaded;
630
631/// In general, the application is responsible for choosing the `Io`
632/// implementation and library code should accept an `Io` parameter rather than
633/// accessing this declaration. Most code should avoid referencing this
634/// declaration entirely.
635///
636/// However, in some cases such as debugging, it is desirable to hardcode a
637/// reference to this `Io` implementation.
638///
639/// This instance does not support concurrency or cancelation.
640pub const global_single_threaded: *Threaded = &global_single_threaded_instance;
641
629pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void {642pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void {
630 t.mutex.lock();643 t.mutex.lock();
631 defer t.mutex.unlock();644 defer t.mutex.unlock();
lib/std/Thread.zig+1-2
...@@ -322,8 +322,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co...@@ -322,8 +322,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
322 var buf: [32]u8 = undefined;322 var buf: [32]u8 = undefined;
323 const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()});323 const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()});
324324
325 var threaded: std.Io.Threaded = .init_single_threaded;325 const io = Io.Threaded.global_single_threaded.ioBasic();
326 const io = threaded.ioBasic();
327326
328 const file = try Io.Dir.cwd().openFile(io, path, .{});327 const file = try Io.Dir.cwd().openFile(io, path, .{});
329 defer file.close(io);328 defer file.close(io);
lib/std/debug.zig+6-6
...@@ -263,7 +263,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) {...@@ -263,7 +263,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) {
263263
264/// This is used for debug information and debug printing. It is intentionally264/// This is used for debug information and debug printing. It is intentionally
265/// separate from the application's `Io` instance.265/// separate from the application's `Io` instance.
266var static_single_threaded_io: Io.Threaded = .init_single_threaded;266const static_single_threaded_io = Io.Threaded.global_single_threaded.ioBasic();
267267
268/// Allows the caller to freely write to stderr until `unlockStderr` is called.268/// Allows the caller to freely write to stderr until `unlockStderr` is called.
269///269///
...@@ -284,7 +284,7 @@ var static_single_threaded_io: Io.Threaded = .init_single_threaded;...@@ -284,7 +284,7 @@ var static_single_threaded_io: Io.Threaded = .init_single_threaded;
284/// Alternatively, use the higher-level `Io.lockStderr` to integrate with the284/// Alternatively, use the higher-level `Io.lockStderr` to integrate with the
285/// application's chosen `Io` implementation.285/// application's chosen `Io` implementation.
286pub fn lockStderr(buffer: []u8) Io.LockedStderr {286pub fn lockStderr(buffer: []u8) Io.LockedStderr {
287 return static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) {287 return static_single_threaded_io.lockStderr(buffer, null) catch |err| switch (err) {
288 // Impossible to cancel because no calls to cancel using288 // Impossible to cancel because no calls to cancel using
289 // `static_single_threaded_io` exist.289 // `static_single_threaded_io` exist.
290 error.Canceled => unreachable,290 error.Canceled => unreachable,
...@@ -292,7 +292,7 @@ pub fn lockStderr(buffer: []u8) Io.LockedStderr {...@@ -292,7 +292,7 @@ pub fn lockStderr(buffer: []u8) Io.LockedStderr {
292}292}
293293
294pub fn unlockStderr() void {294pub fn unlockStderr() void {
295 static_single_threaded_io.ioBasic().unlockStderr();295 static_single_threaded_io.unlockStderr();
296}296}
297297
298/// Writes to stderr, ignoring errors.298/// Writes to stderr, ignoring errors.
...@@ -630,7 +630,7 @@ pub noinline fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf:...@@ -630,7 +630,7 @@ pub noinline fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf:
630 defer it.deinit();630 defer it.deinit();
631 if (!it.stratOk(options.allow_unsafe_unwind)) return empty_trace;631 if (!it.stratOk(options.allow_unsafe_unwind)) return empty_trace;
632632
633 const io = static_single_threaded_io.ioBasic();633 const io = static_single_threaded_io;
634634
635 var total_frames: usize = 0;635 var total_frames: usize = 0;
636 var index: usize = 0;636 var index: usize = 0;
...@@ -692,7 +692,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, t: Io.Termin...@@ -692,7 +692,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, t: Io.Termin
692 var total_frames: usize = 0;692 var total_frames: usize = 0;
693 var wait_for = options.first_address;693 var wait_for = options.first_address;
694 var printed_any_frame = false;694 var printed_any_frame = false;
695 const io = static_single_threaded_io.ioBasic();695 const io = static_single_threaded_io;
696 while (true) switch (it.next(io)) {696 while (true) switch (it.next(io)) {
697 .switch_to_fp => |unwind_error| {697 .switch_to_fp => |unwind_error| {
698 switch (StackIterator.fp_usability) {698 switch (StackIterator.fp_usability) {
...@@ -800,7 +800,7 @@ pub fn writeStackTrace(st: *const StackTrace, t: Io.Terminal) Writer.Error!void...@@ -800,7 +800,7 @@ pub fn writeStackTrace(st: *const StackTrace, t: Io.Terminal) Writer.Error!void
800 return;800 return;
801 },801 },
802 };802 };
803 const io = static_single_threaded_io.ioBasic();803 const io = static_single_threaded_io;
804 const captured_frames = @min(n_frames, st.instruction_addresses.len);804 const captured_frames = @min(n_frames, st.instruction_addresses.len);
805 for (st.instruction_addresses[0..captured_frames]) |ret_addr| {805 for (st.instruction_addresses[0..captured_frames]) |ret_addr| {
806 // `ret_addr` is the return address, which is *after* the function call.806 // `ret_addr` is the return address, which is *after* the function call.
lib/std/debug/SelfInfo/Windows.zig+2-2
...@@ -315,8 +315,8 @@ const Module = struct {...@@ -315,8 +315,8 @@ const Module = struct {
315 );315 );
316 if (len == 0) return error.MissingDebugInfo;316 if (len == 0) return error.MissingDebugInfo;
317 const name_w = name_buffer[0 .. len + 4 :0];317 const name_w = name_buffer[0 .. len + 4 :0];
318 var threaded: Io.Threaded = .init_single_threaded;318 // TODO eliminate the reference to Io.Threaded.global_single_threaded here
319 const coff_file = threaded.dirOpenFileWtf16(null, name_w, .{}) catch |err| switch (err) {319 const coff_file = Io.Threaded.global_single_threaded.dirOpenFileWtf16(null, name_w, .{}) catch |err| switch (err) {
320 error.Canceled => |e| return e,320 error.Canceled => |e| return e,
321 error.Unexpected => |e| return e,321 error.Unexpected => |e| return e,
322 error.FileNotFound => return error.MissingDebugInfo,322 error.FileNotFound => return error.MissingDebugInfo,
lib/std/dynamic_library.zig+1-3
...@@ -142,8 +142,6 @@ const ElfDynLibError = error{...@@ -142,8 +142,6 @@ const ElfDynLibError = error{
142 Streaming,142 Streaming,
143} || posix.OpenError || posix.MMapError;143} || posix.OpenError || posix.MMapError;
144144
145var static_single_threaded_io: Io.Threaded = .init_single_threaded;
146
147pub const ElfDynLib = struct {145pub const ElfDynLib = struct {
148 strings: [*:0]u8,146 strings: [*:0]u8,
149 syms: [*]elf.Sym,147 syms: [*]elf.Sym,
...@@ -224,7 +222,7 @@ pub const ElfDynLib = struct {...@@ -224,7 +222,7 @@ pub const ElfDynLib = struct {
224222
225 /// Trusts the file. Malicious file will be able to execute arbitrary code.223 /// Trusts the file. Malicious file will be able to execute arbitrary code.
226 pub fn open(path: []const u8) Error!ElfDynLib {224 pub fn open(path: []const u8) Error!ElfDynLib {
227 const io = static_single_threaded_io.ioBasic();225 const io = Io.Threaded.global_single_threaded.ioBasic();
228226
229 const fd = try resolveFromName(io, path);227 const fd = try resolveFromName(io, path);
230 defer posix.close(fd);228 defer posix.close(fd);
lib/std/process/Child.zig+7-8
...@@ -266,7 +266,7 @@ pub fn spawn(self: *Child, io: Io) SpawnError!void {...@@ -266,7 +266,7 @@ pub fn spawn(self: *Child, io: Io) SpawnError!void {
266 }266 }
267267
268 if (native_os == .windows) {268 if (native_os == .windows) {
269 return self.spawnWindows();269 return self.spawnWindows(io);
270 } else {270 } else {
271 return self.spawnPosix(io);271 return self.spawnPosix(io);
272 }272 }
...@@ -750,7 +750,7 @@ fn spawnPosix(self: *Child, io: Io) SpawnError!void {...@@ -750,7 +750,7 @@ fn spawnPosix(self: *Child, io: Io) SpawnError!void {
750 self.progress_node.setIpcFd(prog_pipe[0]);750 self.progress_node.setIpcFd(prog_pipe[0]);
751}751}
752752
753fn spawnWindows(self: *Child) SpawnError!void {753fn spawnWindows(self: *Child, io: Io) SpawnError!void {
754 var saAttr = windows.SECURITY_ATTRIBUTES{754 var saAttr = windows.SECURITY_ATTRIBUTES{
755 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),755 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
756 .bInheritHandle = windows.TRUE,756 .bInheritHandle = windows.TRUE,
...@@ -953,7 +953,7 @@ fn spawnWindows(self: *Child) SpawnError!void {...@@ -953,7 +953,7 @@ fn spawnWindows(self: *Child) SpawnError!void {
953 try dir_buf.appendSlice(self.allocator, app_dir);953 try dir_buf.appendSlice(self.allocator, app_dir);
954 }954 }
955955
956 windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo) catch |no_path_err| {956 windowsCreateProcessPathExt(self.allocator, io, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo) catch |no_path_err| {
957 const original_err = switch (no_path_err) {957 const original_err = switch (no_path_err) {
958 // argv[0] contains unsupported characters that will never resolve to a valid exe.958 // argv[0] contains unsupported characters that will never resolve to a valid exe.
959 error.InvalidArg0 => return error.FileNotFound,959 error.InvalidArg0 => return error.FileNotFound,
...@@ -977,7 +977,7 @@ fn spawnWindows(self: *Child) SpawnError!void {...@@ -977,7 +977,7 @@ fn spawnWindows(self: *Child) SpawnError!void {
977 dir_buf.clearRetainingCapacity();977 dir_buf.clearRetainingCapacity();
978 try dir_buf.appendSlice(self.allocator, search_path);978 try dir_buf.appendSlice(self.allocator, search_path);
979979
980 if (windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo)) {980 if (windowsCreateProcessPathExt(self.allocator, io, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo)) {
981 break :run;981 break :run;
982 } else |err| switch (err) {982 } else |err| switch (err) {
983 // argv[0] contains unsupported characters that will never resolve to a valid exe.983 // argv[0] contains unsupported characters that will never resolve to a valid exe.
...@@ -1079,6 +1079,7 @@ const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8);...@@ -1079,6 +1079,7 @@ const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8);
1079/// Note: If the dir is the cwd, dir_buf should be empty (len = 0).1079/// Note: If the dir is the cwd, dir_buf should be empty (len = 0).
1080fn windowsCreateProcessPathExt(1080fn windowsCreateProcessPathExt(
1081 allocator: Allocator,1081 allocator: Allocator,
1082 io: Io,
1082 dir_buf: *ArrayList(u16),1083 dir_buf: *ArrayList(u16),
1083 app_buf: *ArrayList(u16),1084 app_buf: *ArrayList(u16),
1084 pathext: [:0]const u16,1085 pathext: [:0]const u16,
...@@ -1122,16 +1123,14 @@ fn windowsCreateProcessPathExt(...@@ -1122,16 +1123,14 @@ fn windowsCreateProcessPathExt(
1122 // Under those conditions, here we will have access to lower level directory1123 // Under those conditions, here we will have access to lower level directory
1123 // opening function knowing which implementation we are in. Here, we imitate1124 // opening function knowing which implementation we are in. Here, we imitate
1124 // that scenario.1125 // that scenario.
1125 var threaded: std.Io.Threaded = .init_single_threaded;
1126 const io = threaded.ioBasic();
1127
1128 var dir = dir: {1126 var dir = dir: {
1129 // needs to be null-terminated1127 // needs to be null-terminated
1130 try dir_buf.append(allocator, 0);1128 try dir_buf.append(allocator, 0);
1131 defer dir_buf.shrinkRetainingCapacity(dir_path_len);1129 defer dir_buf.shrinkRetainingCapacity(dir_path_len);
1132 const dir_path_z = dir_buf.items[0 .. dir_buf.items.len - 1 :0];1130 const dir_path_z = dir_buf.items[0 .. dir_buf.items.len - 1 :0];
1133 const prefixed_path = try windows.wToPrefixedFileW(null, dir_path_z);1131 const prefixed_path = try windows.wToPrefixedFileW(null, dir_path_z);
1134 break :dir threaded.dirOpenDirWindows(.cwd(), prefixed_path.span(), .{1132 // TODO eliminate this reference
1133 break :dir Io.Threaded.global_single_threaded.dirOpenDirWindows(.cwd(), prefixed_path.span(), .{
1135 .iterate = true,1134 .iterate = true,
1136 }) catch return error.FileNotFound;1135 }) catch return error.FileNotFound;
1137 };1136 };
test/incremental/no_change_preserves_tag_names+2-2
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8const std = @import("std");8const std = @import("std");
9var some_enum: enum { first, second } = .first;9var some_enum: enum { first, second } = .first;
10pub fn main() !void {10pub fn main() !void {
11 try std.Io.File.stdout().writeAll(@tagName(some_enum));11 try std.Io.File.stdout().writeStreamingAll(std.Io.Threaded.global_single_threaded.ioBasic(), @tagName(some_enum));
12}12}
13#expect_stdout="first"13#expect_stdout="first"
14#update=no change14#update=no change
...@@ -16,6 +16,6 @@ pub fn main() !void {...@@ -16,6 +16,6 @@ pub fn main() !void {
16const std = @import("std");16const std = @import("std");
17var some_enum: enum { first, second } = .first;17var some_enum: enum { first, second } = .first;
18pub fn main() !void {18pub fn main() !void {
19 try std.Io.File.stdout().writeAll(@tagName(some_enum));19 try std.Io.File.stdout().writeStreamingAll(std.Io.Threaded.global_single_threaded.ioBasic(), @tagName(some_enum));
20}20}
21#expect_stdout="first"21#expect_stdout="first"
test/standalone/cmakedefine/check.zig+1-2
...@@ -9,8 +9,7 @@ pub fn main() !void {...@@ -9,8 +9,7 @@ pub fn main() !void {
9 const actual_path = args[1];9 const actual_path = args[1];
10 const expected_path = args[2];10 const expected_path = args[2];
1111
12 var threaded: std.Io.Threaded = .init_single_threaded;12 const io = std.Io.Threaded.global_single_threaded.ioBasic();
13 const io = threaded.io();
1413
15 const actual = try std.Io.Dir.cwd().readFileAlloc(io, actual_path, arena, .limited(1024 * 1024));14 const actual = try std.Io.Dir.cwd().readFileAlloc(io, actual_path, arena, .limited(1024 * 1024));
16 const expected = try std.Io.Dir.cwd().readFileAlloc(io, expected_path, arena, .limited(1024 * 1024));15 const expected = try std.Io.Dir.cwd().readFileAlloc(io, expected_path, arena, .limited(1024 * 1024));
test/standalone/dirname/exists_in.zig+1-2
...@@ -34,8 +34,7 @@ fn run(allocator: std.mem.Allocator) !void {...@@ -34,8 +34,7 @@ fn run(allocator: std.mem.Allocator) !void {
34 return error.BadUsage;34 return error.BadUsage;
35 };35 };
3636
37 var threaded: std.Io.Threaded = .init_single_threaded;37 const io = std.Io.Threaded.global_single_threaded.ioBasic();
38 const io = threaded.io();
3938
40 var dir = try std.Io.Dir.cwd().openDir(io, dir_path, .{});39 var dir = try std.Io.Dir.cwd().openDir(io, dir_path, .{});
41 defer dir.close(io);40 defer dir.close(io);
test/standalone/dirname/touch.zig+1-2
...@@ -29,8 +29,7 @@ fn run(allocator: std.mem.Allocator) !void {...@@ -29,8 +29,7 @@ fn run(allocator: std.mem.Allocator) !void {
29 const dir_path = std.Io.Dir.path.dirname(path) orelse unreachable;29 const dir_path = std.Io.Dir.path.dirname(path) orelse unreachable;
30 const basename = std.Io.Dir.path.basename(path);30 const basename = std.Io.Dir.path.basename(path);
3131
32 var threaded: std.Io.Threaded = .init_single_threaded;32 const io = std.Io.Threaded.global_single_threaded.ioBasic();
33 const io = threaded.io();
3433
35 var dir = try std.Io.Dir.cwd().openDir(io, dir_path, .{});34 var dir = try std.Io.Dir.cwd().openDir(io, dir_path, .{});
36 defer dir.close(io);35 defer dir.close(io);
test/standalone/entry_point/check_differ.zig+1-2
...@@ -6,8 +6,7 @@ pub fn main() !void {...@@ -6,8 +6,7 @@ pub fn main() !void {
6 const args = try std.process.argsAlloc(arena);6 const args = try std.process.argsAlloc(arena);
7 if (args.len != 3) return error.BadUsage; // usage: 'check_differ <path a> <path b>'7 if (args.len != 3) return error.BadUsage; // usage: 'check_differ <path a> <path b>'
88
9 var threaded: std.Io.Threaded = .init_single_threaded;9 const io = std.Io.Threaded.global_single_threaded.ioBasic();
10 const io = threaded.io();
1110
12 const contents_1 = try std.Io.Dir.cwd().readFileAlloc(io, args[1], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty11 const contents_1 = try std.Io.Dir.cwd().readFileAlloc(io, args[1], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty
13 const contents_2 = try std.Io.Dir.cwd().readFileAlloc(io, args[2], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty12 const contents_2 = try std.Io.Dir.cwd().readFileAlloc(io, args[2], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty
test/standalone/install_headers/check_exists.zig+1-2
...@@ -11,8 +11,7 @@ pub fn main() !void {...@@ -11,8 +11,7 @@ pub fn main() !void {
11 var arg_it = try std.process.argsWithAllocator(arena);11 var arg_it = try std.process.argsWithAllocator(arena);
12 _ = arg_it.next();12 _ = arg_it.next();
1313
14 var threaded: std.Io.Threaded = .init_single_threaded;14 const io = std.Io.Threaded.global_single_threaded.ioBasic();
15 const io = threaded.io();
1615
17 const cwd = std.Io.Dir.cwd();16 const cwd = std.Io.Dir.cwd();
18 const cwd_realpath = try cwd.realPathAlloc(io, arena, ".");17 const cwd_realpath = try cwd.realPathAlloc(io, arena, ".");
test/standalone/posix/relpaths.zig+1-2
...@@ -14,8 +14,7 @@ pub fn main() !void {...@@ -14,8 +14,7 @@ pub fn main() !void {
14 const gpa = debug_allocator.allocator();14 const gpa = debug_allocator.allocator();
15 defer std.debug.assert(debug_allocator.deinit() == .ok);15 defer std.debug.assert(debug_allocator.deinit() == .ok);
1616
17 var threaded: std.Io.Threaded = .init_single_threaded;17 const io = std.Io.Threaded.global_single_threaded.ioBasic();
18 const io = threaded.io();
1918
20 // TODO this API isn't supposed to be used outside of unit testing. make it compilation error if used19 // TODO this API isn't supposed to be used outside of unit testing. make it compilation error if used
21 // outside of unit testing.20 // outside of unit testing.
test/standalone/run_cwd/check_file_exists.zig+1-2
...@@ -8,8 +8,7 @@ pub fn main() !void {...@@ -8,8 +8,7 @@ pub fn main() !void {
8 if (args.len != 2) return error.BadUsage;8 if (args.len != 2) return error.BadUsage;
9 const path = args[1];9 const path = args[1];
1010
11 var threaded: std.Io.Threaded = .init_single_threaded;11 const io = std.Io.Threaded.global_single_threaded.ioBasic();
12 const io = threaded.io();
1312
14 std.Io.Dir.cwd().access(io, path, .{}) catch return error.AccessFailed;13 std.Io.Dir.cwd().access(io, path, .{}) catch return error.AccessFailed;
15}14}
test/standalone/run_output_caching/main.zig+1-2
...@@ -1,8 +1,7 @@...@@ -1,8 +1,7 @@
1const std = @import("std");1const std = @import("std");
22
3pub fn main() !void {3pub fn main() !void {
4 var threaded: std.Io.Threaded = .init_single_threaded;4 const io = std.Io.Threaded.global_single_threaded.ioBasic();
5 const io = threaded.io();
6 var args = try std.process.argsWithAllocator(std.heap.page_allocator);5 var args = try std.process.argsWithAllocator(std.heap.page_allocator);
7 _ = args.skip();6 _ = args.skip();
8 const filename = args.next().?;7 const filename = args.next().?;
test/standalone/run_output_paths/create_file.zig+1-2
...@@ -1,8 +1,7 @@...@@ -1,8 +1,7 @@
1const std = @import("std");1const std = @import("std");
22
3pub fn main() !void {3pub fn main() !void {
4 var threaded: std.Io.Threaded = .init_single_threaded;4 const io = std.Io.Threaded.global_single_threaded.ioBasic();
5 const io = threaded.io();
6 var args = try std.process.argsWithAllocator(std.heap.page_allocator);5 var args = try std.process.argsWithAllocator(std.heap.page_allocator);
7 _ = args.skip();6 _ = args.skip();
8 const dir_name = args.next().?;7 const dir_name = args.next().?;
test/standalone/self_exe_symlink/create-symlink.zig+1-2
...@@ -15,8 +15,7 @@ pub fn main() anyerror!void {...@@ -15,8 +15,7 @@ pub fn main() anyerror!void {
15 const exe_rel_path = try std.fs.path.relative(allocator, std.fs.path.dirname(symlink_path) orelse ".", exe_path);15 const exe_rel_path = try std.fs.path.relative(allocator, std.fs.path.dirname(symlink_path) orelse ".", exe_path);
16 defer allocator.free(exe_rel_path);16 defer allocator.free(exe_rel_path);
1717
18 var threaded: std.Io.Threaded = .init_single_threaded;18 const io = std.Io.Threaded.global_single_threaded.ioBasic();
19 const io = threaded.io();
2019
21 try std.Io.Dir.cwd().symLink(io, exe_rel_path, symlink_path, .{});20 try std.Io.Dir.cwd().symLink(io, exe_rel_path, symlink_path, .{});
22}21}
test/standalone/simple/hello_world/hello.zig+8-3
...@@ -1,8 +1,13 @@...@@ -1,8 +1,13 @@
1const std = @import("std");1const std = @import("std");
22
3var static_single_threaded_io: std.Io.Threaded = .init_single_threaded;
4const io = static_single_threaded_io.ioBasic();
5
6pub fn main() !void {3pub fn main() !void {
4 var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
5 defer _ = debug_allocator.deinit();
6 const gpa = debug_allocator.allocator();
7
8 var threaded: std.Io.Threaded = .init(gpa);
9 defer threaded.deinit();
10 const io = threaded.io();
11
7 try std.Io.File.stdout().writeStreamingAll(io, "Hello, World!\n");12 try std.Io.File.stdout().writeStreamingAll(io, "Hello, World!\n");
8}13}
test/standalone/windows_paths/test.zig+1-2
...@@ -10,8 +10,7 @@ pub fn main() anyerror!void {...@@ -10,8 +10,7 @@ pub fn main() anyerror!void {
1010
11 if (args.len < 2) return error.MissingArgs;11 if (args.len < 2) return error.MissingArgs;
1212
13 var threaded: Io.Threaded = .init_single_threaded;13 const io = std.Io.Threaded.global_single_threaded.ioBasic();
14 const io = threaded.io();
1514
16 const exe_path = args[1];15 const exe_path = args[1];
1716