From 77d2ad8c929680ed35fcfe6646f940518a07e7e4 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 19 Dec 2025 20:15:50 -0800 Subject: [PATCH] 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. --- lib/compiler/test_runner.zig | 10 +++++----- lib/std/Io/Threaded.zig | 13 +++++++++++++ lib/std/Thread.zig | 3 +-- lib/std/debug.zig | 12 ++++++------ lib/std/debug/SelfInfo/Windows.zig | 4 ++-- lib/std/dynamic_library.zig | 4 +--- lib/std/process/Child.zig | 15 +++++++-------- test/incremental/no_change_preserves_tag_names | 4 ++-- test/standalone/cmakedefine/check.zig | 3 +-- test/standalone/dirname/exists_in.zig | 3 +-- test/standalone/dirname/touch.zig | 3 +-- test/standalone/entry_point/check_differ.zig | 3 +-- test/standalone/install_headers/check_exists.zig | 3 +-- test/standalone/posix/relpaths.zig | 3 +-- test/standalone/run_cwd/check_file_exists.zig | 3 +-- test/standalone/run_output_caching/main.zig | 3 +-- test/standalone/run_output_paths/create_file.zig | 3 +-- .../self_exe_symlink/create-symlink.zig | 3 +-- test/standalone/simple/hello_world/hello.zig | 11 ++++++++--- test/standalone/windows_paths/test.zig | 3 +-- 20 files changed, 56 insertions(+), 53 deletions(-) diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index d16fc3ae82f83160aa60fff434b73f50427a4c73..84664feb138d556bafc4a9a90223f79d375f6d92 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -17,7 +17,7 @@ var fba: std.heap.FixedBufferAllocator = .init(&fba_buffer); var fba_buffer: [8192]u8 = undefined; var stdin_buffer: [4096]u8 = undefined; var stdout_buffer: [4096]u8 = undefined; -var runner_threaded_io: Io.Threaded = .init_single_threaded; +const runner_threaded_io: Io = Io.Threaded.global_single_threaded.ioBasic(); /// Keep in sync with logic in `std.Build.addRunArtifact` which decides whether /// the test runner will communicate with the build runner via `std.zig.Server`. @@ -74,8 +74,8 @@ pub fn main() void { fn mainServer() !void { @disableInstrumentation(); - var stdin_reader = Io.File.stdin().readerStreaming(runner_threaded_io.io(), &stdin_buffer); - var stdout_writer = Io.File.stdout().writerStreaming(runner_threaded_io.io(), &stdout_buffer); + var stdin_reader = Io.File.stdin().readerStreaming(runner_threaded_io, &stdin_buffer); + var stdout_writer = Io.File.stdout().writerStreaming(runner_threaded_io, &stdout_buffer); var server = try std.zig.Server.init(.{ .in = &stdin_reader.interface, .out = &stdout_writer.interface, @@ -224,11 +224,11 @@ fn mainTerminal() void { var skip_count: usize = 0; var fail_count: usize = 0; var fuzz_count: usize = 0; - const root_node = if (builtin.fuzz) std.Progress.Node.none else std.Progress.start(runner_threaded_io.io(), .{ + const root_node = if (builtin.fuzz) std.Progress.Node.none else std.Progress.start(runner_threaded_io, .{ .root_name = "Test", .estimated_total_items = test_fn_list.len, }); - const have_tty = Io.File.stderr().isTty(runner_threaded_io.io()) catch unreachable; + const have_tty = Io.File.stderr().isTty(runner_threaded_io) catch unreachable; var leaks: usize = 0; for (test_fn_list, 0..) |test_fn, i| { diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index db4c5f3fda98fa2d18f237a96b19ef23bd5937d3..182a8f4b6d45ae6561bb8ae6fca88a86d6bbe790 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -626,6 +626,19 @@ pub const init_single_threaded: Threaded = .{ }, }; +var global_single_threaded_instance: Threaded = .init_single_threaded; + +/// In general, the application is responsible for choosing the `Io` +/// implementation and library code should accept an `Io` parameter rather than +/// accessing this declaration. Most code should avoid referencing this +/// declaration entirely. +/// +/// However, in some cases such as debugging, it is desirable to hardcode a +/// reference to this `Io` implementation. +/// +/// This instance does not support concurrency or cancelation. +pub const global_single_threaded: *Threaded = &global_single_threaded_instance; + pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void { t.mutex.lock(); defer t.mutex.unlock(); diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index fbce1cd000381b835642f87916850297170aa4c2..f25c664000fbcbb737619c331a08bcb013d7ac71 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -322,8 +322,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co var buf: [32]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()}); - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.ioBasic(); + const io = Io.Threaded.global_single_threaded.ioBasic(); const file = try Io.Dir.cwd().openFile(io, path, .{}); defer file.close(io); diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 26631db5012d9e7b56688768671af46dc891165c..0e804e23483fd52230b7862e3357a14e02b46c0e 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -263,7 +263,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) { /// This is used for debug information and debug printing. It is intentionally /// separate from the application's `Io` instance. -var static_single_threaded_io: Io.Threaded = .init_single_threaded; +const static_single_threaded_io = Io.Threaded.global_single_threaded.ioBasic(); /// Allows the caller to freely write to stderr until `unlockStderr` is called. /// @@ -284,7 +284,7 @@ var static_single_threaded_io: Io.Threaded = .init_single_threaded; /// Alternatively, use the higher-level `Io.lockStderr` to integrate with the /// application's chosen `Io` implementation. pub fn lockStderr(buffer: []u8) Io.LockedStderr { - return static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) { + return static_single_threaded_io.lockStderr(buffer, null) catch |err| switch (err) { // Impossible to cancel because no calls to cancel using // `static_single_threaded_io` exist. error.Canceled => unreachable, @@ -292,7 +292,7 @@ pub fn lockStderr(buffer: []u8) Io.LockedStderr { } pub fn unlockStderr() void { - static_single_threaded_io.ioBasic().unlockStderr(); + static_single_threaded_io.unlockStderr(); } /// Writes to stderr, ignoring errors. @@ -630,7 +630,7 @@ pub noinline fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf: defer it.deinit(); if (!it.stratOk(options.allow_unsafe_unwind)) return empty_trace; - const io = static_single_threaded_io.ioBasic(); + const io = static_single_threaded_io; var total_frames: usize = 0; var index: usize = 0; @@ -692,7 +692,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, t: Io.Termin var total_frames: usize = 0; var wait_for = options.first_address; var printed_any_frame = false; - const io = static_single_threaded_io.ioBasic(); + const io = static_single_threaded_io; while (true) switch (it.next(io)) { .switch_to_fp => |unwind_error| { switch (StackIterator.fp_usability) { @@ -800,7 +800,7 @@ pub fn writeStackTrace(st: *const StackTrace, t: Io.Terminal) Writer.Error!void return; }, }; - const io = static_single_threaded_io.ioBasic(); + const io = static_single_threaded_io; const captured_frames = @min(n_frames, st.instruction_addresses.len); for (st.instruction_addresses[0..captured_frames]) |ret_addr| { // `ret_addr` is the return address, which is *after* the function call. diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig index c34c60f3ec2ede798bb10822b0ece7a59f67098c..99d3e9f92623696c67b3afdd33f75b459d1cce2d 100644 --- a/lib/std/debug/SelfInfo/Windows.zig +++ b/lib/std/debug/SelfInfo/Windows.zig @@ -315,8 +315,8 @@ const Module = struct { ); if (len == 0) return error.MissingDebugInfo; const name_w = name_buffer[0 .. len + 4 :0]; - var threaded: Io.Threaded = .init_single_threaded; - const coff_file = threaded.dirOpenFileWtf16(null, name_w, .{}) catch |err| switch (err) { + // TODO eliminate the reference to Io.Threaded.global_single_threaded here + const coff_file = Io.Threaded.global_single_threaded.dirOpenFileWtf16(null, name_w, .{}) catch |err| switch (err) { error.Canceled => |e| return e, error.Unexpected => |e| return e, error.FileNotFound => return error.MissingDebugInfo, diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index 18db4ad8c6e4b224547321d5d01ab07cf5534c57..70b236f3e5902cb48bb6b2794ade1baacaa8bca0 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -142,8 +142,6 @@ const ElfDynLibError = error{ Streaming, } || posix.OpenError || posix.MMapError; -var static_single_threaded_io: Io.Threaded = .init_single_threaded; - pub const ElfDynLib = struct { strings: [*:0]u8, syms: [*]elf.Sym, @@ -224,7 +222,7 @@ pub const ElfDynLib = struct { /// Trusts the file. Malicious file will be able to execute arbitrary code. pub fn open(path: []const u8) Error!ElfDynLib { - const io = static_single_threaded_io.ioBasic(); + const io = Io.Threaded.global_single_threaded.ioBasic(); const fd = try resolveFromName(io, path); defer posix.close(fd); diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index 05cc4b39449ec6cd80ebdf5b186e77209b2d8211..0db02aa824309ef653e071be0b6c095ff5c58c5d 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -266,7 +266,7 @@ pub fn spawn(self: *Child, io: Io) SpawnError!void { } if (native_os == .windows) { - return self.spawnWindows(); + return self.spawnWindows(io); } else { return self.spawnPosix(io); } @@ -750,7 +750,7 @@ fn spawnPosix(self: *Child, io: Io) SpawnError!void { self.progress_node.setIpcFd(prog_pipe[0]); } -fn spawnWindows(self: *Child) SpawnError!void { +fn spawnWindows(self: *Child, io: Io) SpawnError!void { var saAttr = windows.SECURITY_ATTRIBUTES{ .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES), .bInheritHandle = windows.TRUE, @@ -953,7 +953,7 @@ fn spawnWindows(self: *Child) SpawnError!void { try dir_buf.appendSlice(self.allocator, app_dir); } - windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo) catch |no_path_err| { + windowsCreateProcessPathExt(self.allocator, io, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo) catch |no_path_err| { const original_err = switch (no_path_err) { // argv[0] contains unsupported characters that will never resolve to a valid exe. error.InvalidArg0 => return error.FileNotFound, @@ -977,7 +977,7 @@ fn spawnWindows(self: *Child) SpawnError!void { dir_buf.clearRetainingCapacity(); try dir_buf.appendSlice(self.allocator, search_path); - if (windowsCreateProcessPathExt(self.allocator, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo)) { + if (windowsCreateProcessPathExt(self.allocator, io, &dir_buf, &app_buf, PATHEXT, &cmd_line_cache, envp_ptr, cwd_w_ptr, flags, &siStartInfo, &piProcInfo)) { break :run; } else |err| switch (err) { // 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); /// Note: If the dir is the cwd, dir_buf should be empty (len = 0). fn windowsCreateProcessPathExt( allocator: Allocator, + io: Io, dir_buf: *ArrayList(u16), app_buf: *ArrayList(u16), pathext: [:0]const u16, @@ -1122,16 +1123,14 @@ fn windowsCreateProcessPathExt( // Under those conditions, here we will have access to lower level directory // opening function knowing which implementation we are in. Here, we imitate // that scenario. - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.ioBasic(); - var dir = dir: { // needs to be null-terminated try dir_buf.append(allocator, 0); defer dir_buf.shrinkRetainingCapacity(dir_path_len); const dir_path_z = dir_buf.items[0 .. dir_buf.items.len - 1 :0]; const prefixed_path = try windows.wToPrefixedFileW(null, dir_path_z); - break :dir threaded.dirOpenDirWindows(.cwd(), prefixed_path.span(), .{ + // TODO eliminate this reference + break :dir Io.Threaded.global_single_threaded.dirOpenDirWindows(.cwd(), prefixed_path.span(), .{ .iterate = true, }) catch return error.FileNotFound; }; diff --git a/test/incremental/no_change_preserves_tag_names b/test/incremental/no_change_preserves_tag_names index e399e083e10e198858d1243259e2ed5a0cc9274f..6675d74166016b849c93aaf5663d6d6354770070 100644 --- a/test/incremental/no_change_preserves_tag_names +++ b/test/incremental/no_change_preserves_tag_names @@ -8,7 +8,7 @@ const std = @import("std"); var some_enum: enum { first, second } = .first; pub fn main() !void { - try std.Io.File.stdout().writeAll(@tagName(some_enum)); + try std.Io.File.stdout().writeStreamingAll(std.Io.Threaded.global_single_threaded.ioBasic(), @tagName(some_enum)); } #expect_stdout="first" #update=no change @@ -16,6 +16,6 @@ pub fn main() !void { const std = @import("std"); var some_enum: enum { first, second } = .first; pub fn main() !void { - try std.Io.File.stdout().writeAll(@tagName(some_enum)); + try std.Io.File.stdout().writeStreamingAll(std.Io.Threaded.global_single_threaded.ioBasic(), @tagName(some_enum)); } #expect_stdout="first" diff --git a/test/standalone/cmakedefine/check.zig b/test/standalone/cmakedefine/check.zig index d0751913d755d1fe4d175ed9d6f3c8f6d13fdaef..c2f89ad1127ccba3f663886e84d085cab2f7cb26 100644 --- a/test/standalone/cmakedefine/check.zig +++ b/test/standalone/cmakedefine/check.zig @@ -9,8 +9,7 @@ pub fn main() !void { const actual_path = args[1]; const expected_path = args[2]; - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); const actual = try std.Io.Dir.cwd().readFileAlloc(io, actual_path, arena, .limited(1024 * 1024)); const expected = try std.Io.Dir.cwd().readFileAlloc(io, expected_path, arena, .limited(1024 * 1024)); diff --git a/test/standalone/dirname/exists_in.zig b/test/standalone/dirname/exists_in.zig index 7bddc4e61395e1b75accafd37e452f5fc910c167..b321f46c55407cf46d8b12fbe6cc4b8c2323e1cf 100644 --- a/test/standalone/dirname/exists_in.zig +++ b/test/standalone/dirname/exists_in.zig @@ -34,8 +34,7 @@ fn run(allocator: std.mem.Allocator) !void { return error.BadUsage; }; - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); var dir = try std.Io.Dir.cwd().openDir(io, dir_path, .{}); defer dir.close(io); diff --git a/test/standalone/dirname/touch.zig b/test/standalone/dirname/touch.zig index 9255d27c72ebbb182e564e4781c5d888fe47ed52..d7f9b71553a9e1cab81f40f13e118fb30636b6a8 100644 --- a/test/standalone/dirname/touch.zig +++ b/test/standalone/dirname/touch.zig @@ -29,8 +29,7 @@ fn run(allocator: std.mem.Allocator) !void { const dir_path = std.Io.Dir.path.dirname(path) orelse unreachable; const basename = std.Io.Dir.path.basename(path); - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); var dir = try std.Io.Dir.cwd().openDir(io, dir_path, .{}); defer dir.close(io); diff --git a/test/standalone/entry_point/check_differ.zig b/test/standalone/entry_point/check_differ.zig index bba45e5f8cf054efd464270e8ad5b405b5f12267..29b333632fcd0f7d823f4b1caf501a2b7e7ca06d 100644 --- a/test/standalone/entry_point/check_differ.zig +++ b/test/standalone/entry_point/check_differ.zig @@ -6,8 +6,7 @@ pub fn main() !void { const args = try std.process.argsAlloc(arena); if (args.len != 3) return error.BadUsage; // usage: 'check_differ ' - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); const contents_1 = try std.Io.Dir.cwd().readFileAlloc(io, args[1], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty const contents_2 = try std.Io.Dir.cwd().readFileAlloc(io, args[2], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty diff --git a/test/standalone/install_headers/check_exists.zig b/test/standalone/install_headers/check_exists.zig index 8a7104e4f2072dcf002528a7340c5191630ba37e..22638cf1676080941c3b8b1a451d0c76e50306b8 100644 --- a/test/standalone/install_headers/check_exists.zig +++ b/test/standalone/install_headers/check_exists.zig @@ -11,8 +11,7 @@ pub fn main() !void { var arg_it = try std.process.argsWithAllocator(arena); _ = arg_it.next(); - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); const cwd = std.Io.Dir.cwd(); const cwd_realpath = try cwd.realPathAlloc(io, arena, "."); diff --git a/test/standalone/posix/relpaths.zig b/test/standalone/posix/relpaths.zig index ed143ccdc232ac2263ee0fc0fd3f51528654a6bc..447285c444d457a1fe1f2f0a1c1f1b696540136f 100644 --- a/test/standalone/posix/relpaths.zig +++ b/test/standalone/posix/relpaths.zig @@ -14,8 +14,7 @@ pub fn main() !void { const gpa = debug_allocator.allocator(); defer std.debug.assert(debug_allocator.deinit() == .ok); - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); // TODO this API isn't supposed to be used outside of unit testing. make it compilation error if used // outside of unit testing. diff --git a/test/standalone/run_cwd/check_file_exists.zig b/test/standalone/run_cwd/check_file_exists.zig index 8830cc115a569475332122f604fa1dd626aa01a7..a885c7dafde7c501ba794ecbe4b377aa61eab705 100644 --- a/test/standalone/run_cwd/check_file_exists.zig +++ b/test/standalone/run_cwd/check_file_exists.zig @@ -8,8 +8,7 @@ pub fn main() !void { if (args.len != 2) return error.BadUsage; const path = args[1]; - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); std.Io.Dir.cwd().access(io, path, .{}) catch return error.AccessFailed; } diff --git a/test/standalone/run_output_caching/main.zig b/test/standalone/run_output_caching/main.zig index c21d8d0f6bbd8ea21dd41348e7d6cd4dff020383..66e64beda2eeb7e51811b213551e4ddeb02d41aa 100644 --- a/test/standalone/run_output_caching/main.zig +++ b/test/standalone/run_output_caching/main.zig @@ -1,8 +1,7 @@ const std = @import("std"); pub fn main() !void { - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); var args = try std.process.argsWithAllocator(std.heap.page_allocator); _ = args.skip(); const filename = args.next().?; diff --git a/test/standalone/run_output_paths/create_file.zig b/test/standalone/run_output_paths/create_file.zig index 4830790c79e9530a85a7496cf0c40d098cb6ca13..27f741ecaba37aed73f9b7ebe659219b1f034d17 100644 --- a/test/standalone/run_output_paths/create_file.zig +++ b/test/standalone/run_output_paths/create_file.zig @@ -1,8 +1,7 @@ const std = @import("std"); pub fn main() !void { - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); var args = try std.process.argsWithAllocator(std.heap.page_allocator); _ = args.skip(); const dir_name = args.next().?; diff --git a/test/standalone/self_exe_symlink/create-symlink.zig b/test/standalone/self_exe_symlink/create-symlink.zig index 6ccf6596aa89398f1f50db56a02efacfc3317aac..d725207320811408d453104f022b4c6409b67681 100644 --- a/test/standalone/self_exe_symlink/create-symlink.zig +++ b/test/standalone/self_exe_symlink/create-symlink.zig @@ -15,8 +15,7 @@ pub fn main() anyerror!void { const exe_rel_path = try std.fs.path.relative(allocator, std.fs.path.dirname(symlink_path) orelse ".", exe_path); defer allocator.free(exe_rel_path); - var threaded: std.Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); try std.Io.Dir.cwd().symLink(io, exe_rel_path, symlink_path, .{}); } diff --git a/test/standalone/simple/hello_world/hello.zig b/test/standalone/simple/hello_world/hello.zig index d7083942304c4cc24aa71cbfa45221b95c490ff5..6bce8413441ed0421687c90deb058bf7b3fa16d2 100644 --- a/test/standalone/simple/hello_world/hello.zig +++ b/test/standalone/simple/hello_world/hello.zig @@ -1,8 +1,13 @@ const std = @import("std"); -var static_single_threaded_io: std.Io.Threaded = .init_single_threaded; -const io = static_single_threaded_io.ioBasic(); - pub fn main() !void { + var debug_allocator: std.heap.DebugAllocator(.{}) = .init; + defer _ = debug_allocator.deinit(); + const gpa = debug_allocator.allocator(); + + var threaded: std.Io.Threaded = .init(gpa); + defer threaded.deinit(); + const io = threaded.io(); + try std.Io.File.stdout().writeStreamingAll(io, "Hello, World!\n"); } diff --git a/test/standalone/windows_paths/test.zig b/test/standalone/windows_paths/test.zig index f5fa5947666908f888dbac8dcac55522c93cefab..ed4069dc61e6a5121936b34e9628fd21831da3bc 100644 --- a/test/standalone/windows_paths/test.zig +++ b/test/standalone/windows_paths/test.zig @@ -10,8 +10,7 @@ pub fn main() anyerror!void { if (args.len < 2) return error.MissingArgs; - var threaded: Io.Threaded = .init_single_threaded; - const io = threaded.io(); + const io = std.Io.Threaded.global_single_threaded.ioBasic(); const exe_path = args[1]; -- 2.54.0