| author | |
| committer | |
| log | a4f27e8987ef3e2388839b6452b9f485ab82e7b7 |
| tree | 6420c218896c0f44dea7353b8a9c00b01461c2ec |
| parent | b0bea72588c685c1d6439f61d2e842756b5fc496 |
25 files changed, 119 insertions(+), 579 deletions(-)
lib/std/Build/Step/Compile.zig-5| ... | @@ -55,7 +55,6 @@ global_base: ?u64 = null, | ... | @@ -55,7 +55,6 @@ global_base: ?u64 = null, |
| 55 | zig_lib_dir: ?LazyPath, | 55 | zig_lib_dir: ?LazyPath, |
| 56 | exec_cmd_args: ?[]const ?[]const u8, | 56 | exec_cmd_args: ?[]const ?[]const u8, |
| 57 | filter: ?[]const u8, | 57 | filter: ?[]const u8, |
| 58 | test_evented_io: bool = false, | ||
| 59 | test_runner: ?[]const u8, | 58 | test_runner: ?[]const u8, |
| 60 | test_server_mode: bool, | 59 | test_server_mode: bool, |
| 61 | wasi_exec_model: ?std.builtin.WasiExecModel = null, | 60 | wasi_exec_model: ?std.builtin.WasiExecModel = null, |
| ... | @@ -1294,10 +1293,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1294,10 +1293,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1294 | try zig_args.append(filter); | 1293 | try zig_args.append(filter); |
| 1295 | } | 1294 | } |
| 1296 | 1295 | ||
| 1297 | if (self.test_evented_io) { | ||
| 1298 | try zig_args.append("--test-evented-io"); | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | if (self.test_runner) |test_runner| { | 1296 | if (self.test_runner) |test_runner| { |
| 1302 | try zig_args.append("--test-runner"); | 1297 | try zig_args.append("--test-runner"); |
| 1303 | try zig_args.append(b.pathFromRoot(test_runner)); | 1298 | try zig_args.append(b.pathFromRoot(test_runner)); |
lib/std/Build/Step/Run.zig+2-10| ... | @@ -1147,19 +1147,14 @@ fn evalZigTest( | ... | @@ -1147,19 +1147,14 @@ fn evalZigTest( |
| 1147 | test_count = tm_hdr.tests_len; | 1147 | test_count = tm_hdr.tests_len; |
| 1148 | 1148 | ||
| 1149 | const names_bytes = body[@sizeOf(TmHdr)..][0 .. test_count * @sizeOf(u32)]; | 1149 | const names_bytes = body[@sizeOf(TmHdr)..][0 .. test_count * @sizeOf(u32)]; |
| 1150 | const async_frame_lens_bytes = body[@sizeOf(TmHdr) + names_bytes.len ..][0 .. test_count * @sizeOf(u32)]; | 1150 | const expected_panic_msgs_bytes = body[@sizeOf(TmHdr) + names_bytes.len ..][0 .. test_count * @sizeOf(u32)]; |
| 1151 | const expected_panic_msgs_bytes = body[@sizeOf(TmHdr) + names_bytes.len + async_frame_lens_bytes.len ..][0 .. test_count * @sizeOf(u32)]; | 1151 | const string_bytes = body[@sizeOf(TmHdr) + names_bytes.len + expected_panic_msgs_bytes.len ..][0..tm_hdr.string_bytes_len]; |
| 1152 | const string_bytes = body[@sizeOf(TmHdr) + names_bytes.len + async_frame_lens_bytes.len + expected_panic_msgs_bytes.len ..][0..tm_hdr.string_bytes_len]; | ||
| 1153 | 1152 | ||
| 1154 | const names = std.mem.bytesAsSlice(u32, names_bytes); | 1153 | const names = std.mem.bytesAsSlice(u32, names_bytes); |
| 1155 | const async_frame_lens = std.mem.bytesAsSlice(u32, async_frame_lens_bytes); | ||
| 1156 | const expected_panic_msgs = std.mem.bytesAsSlice(u32, expected_panic_msgs_bytes); | 1154 | const expected_panic_msgs = std.mem.bytesAsSlice(u32, expected_panic_msgs_bytes); |
| 1157 | const names_aligned = try arena.alloc(u32, names.len); | 1155 | const names_aligned = try arena.alloc(u32, names.len); |
| 1158 | for (names_aligned, names) |*dest, src| dest.* = src; | 1156 | for (names_aligned, names) |*dest, src| dest.* = src; |
| 1159 | 1157 | ||
| 1160 | const async_frame_lens_aligned = try arena.alloc(u32, async_frame_lens.len); | ||
| 1161 | for (async_frame_lens_aligned, async_frame_lens) |*dest, src| dest.* = src; | ||
| 1162 | |||
| 1163 | const expected_panic_msgs_aligned = try arena.alloc(u32, expected_panic_msgs.len); | 1158 | const expected_panic_msgs_aligned = try arena.alloc(u32, expected_panic_msgs.len); |
| 1164 | for (expected_panic_msgs_aligned, expected_panic_msgs) |*dest, src| dest.* = src; | 1159 | for (expected_panic_msgs_aligned, expected_panic_msgs) |*dest, src| dest.* = src; |
| 1165 | 1160 | ||
| ... | @@ -1167,7 +1162,6 @@ fn evalZigTest( | ... | @@ -1167,7 +1162,6 @@ fn evalZigTest( |
| 1167 | metadata = .{ | 1162 | metadata = .{ |
| 1168 | .string_bytes = try arena.dupe(u8, string_bytes), | 1163 | .string_bytes = try arena.dupe(u8, string_bytes), |
| 1169 | .names = names_aligned, | 1164 | .names = names_aligned, |
| 1170 | .async_frame_lens = async_frame_lens_aligned, | ||
| 1171 | .expected_panic_msgs = expected_panic_msgs_aligned, | 1165 | .expected_panic_msgs = expected_panic_msgs_aligned, |
| 1172 | .next_index = 0, | 1166 | .next_index = 0, |
| 1173 | .prog_node = prog_node, | 1167 | .prog_node = prog_node, |
| ... | @@ -1237,7 +1231,6 @@ fn evalZigTest( | ... | @@ -1237,7 +1231,6 @@ fn evalZigTest( |
| 1237 | 1231 | ||
| 1238 | const TestMetadata = struct { | 1232 | const TestMetadata = struct { |
| 1239 | names: []const u32, | 1233 | names: []const u32, |
| 1240 | async_frame_lens: []const u32, | ||
| 1241 | expected_panic_msgs: []const u32, | 1234 | expected_panic_msgs: []const u32, |
| 1242 | string_bytes: []const u8, | 1235 | string_bytes: []const u8, |
| 1243 | next_index: u32, | 1236 | next_index: u32, |
| ... | @@ -1253,7 +1246,6 @@ fn requestNextTest(in: fs.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr | ... | @@ -1253,7 +1246,6 @@ fn requestNextTest(in: fs.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr |
| 1253 | const i = metadata.next_index; | 1246 | const i = metadata.next_index; |
| 1254 | metadata.next_index += 1; | 1247 | metadata.next_index += 1; |
| 1255 | 1248 | ||
| 1256 | if (metadata.async_frame_lens[i] != 0) continue; | ||
| 1257 | if (metadata.expected_panic_msgs[i] != 0) continue; | 1249 | if (metadata.expected_panic_msgs[i] != 0) continue; |
| 1258 | 1250 | ||
| 1259 | const name = metadata.testName(i); | 1251 | const name = metadata.testName(i); |
lib/std/builtin.zig-1| ... | @@ -732,7 +732,6 @@ pub const CompilerBackend = enum(u64) { | ... | @@ -732,7 +732,6 @@ pub const CompilerBackend = enum(u64) { |
| 732 | pub const TestFn = struct { | 732 | pub const TestFn = struct { |
| 733 | name: []const u8, | 733 | name: []const u8, |
| 734 | func: *const fn () anyerror!void, | 734 | func: *const fn () anyerror!void, |
| 735 | async_frame_size: ?usize, | ||
| 736 | }; | 735 | }; |
| 737 | 736 | ||
| 738 | /// This function type is used by the Zig language code generation and | 737 | /// This function type is used by the Zig language code generation and |
lib/std/child_process.zig+3-12| ... | @@ -493,7 +493,7 @@ pub const ChildProcess = struct { | ... | @@ -493,7 +493,7 @@ pub const ChildProcess = struct { |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | fn spawnPosix(self: *ChildProcess) SpawnError!void { | 495 | fn spawnPosix(self: *ChildProcess) SpawnError!void { |
| 496 | const pipe_flags = if (io.is_async) os.O.NONBLOCK else 0; | 496 | const pipe_flags = 0; |
| 497 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined; | 497 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined; |
| 498 | errdefer if (self.stdin_behavior == StdIo.Pipe) { | 498 | errdefer if (self.stdin_behavior == StdIo.Pipe) { |
| 499 | destroyPipe(stdin_pipe); | 499 | destroyPipe(stdin_pipe); |
| ... | @@ -665,7 +665,6 @@ pub const ChildProcess = struct { | ... | @@ -665,7 +665,6 @@ pub const ChildProcess = struct { |
| 665 | .share_access = windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE, | 665 | .share_access = windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE, |
| 666 | .sa = &saAttr, | 666 | .sa = &saAttr, |
| 667 | .creation = windows.OPEN_EXISTING, | 667 | .creation = windows.OPEN_EXISTING, |
| 668 | .io_mode = .blocking, | ||
| 669 | }) catch |err| switch (err) { | 668 | }) catch |err| switch (err) { |
| 670 | error.PathAlreadyExists => unreachable, // not possible for "NUL" | 669 | error.PathAlreadyExists => unreachable, // not possible for "NUL" |
| 671 | error.PipeBusy => unreachable, // not possible for "NUL" | 670 | error.PipeBusy => unreachable, // not possible for "NUL" |
| ... | @@ -1491,20 +1490,12 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { | ... | @@ -1491,20 +1490,12 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { |
| 1491 | const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); | 1490 | const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); |
| 1492 | 1491 | ||
| 1493 | fn writeIntFd(fd: i32, value: ErrInt) !void { | 1492 | fn writeIntFd(fd: i32, value: ErrInt) !void { |
| 1494 | const file = File{ | 1493 | const file = File{ .handle = fd }; |
| 1495 | .handle = fd, | ||
| 1496 | .capable_io_mode = .blocking, | ||
| 1497 | .intended_io_mode = .blocking, | ||
| 1498 | }; | ||
| 1499 | file.writer().writeInt(u64, @intCast(value), .little) catch return error.SystemResources; | 1494 | file.writer().writeInt(u64, @intCast(value), .little) catch return error.SystemResources; |
| 1500 | } | 1495 | } |
| 1501 | 1496 | ||
| 1502 | fn readIntFd(fd: i32) !ErrInt { | 1497 | fn readIntFd(fd: i32) !ErrInt { |
| 1503 | const file = File{ | 1498 | const file = File{ .handle = fd }; |
| 1504 | .handle = fd, | ||
| 1505 | .capable_io_mode = .blocking, | ||
| 1506 | .intended_io_mode = .blocking, | ||
| 1507 | }; | ||
| 1508 | return @as(ErrInt, @intCast(file.reader().readInt(u64, .little) catch return error.SystemResources)); | 1499 | return @as(ErrInt, @intCast(file.reader().readInt(u64, .little) catch return error.SystemResources)); |
| 1509 | } | 1500 | } |
| 1510 | 1501 |
lib/std/debug.zig+5-8| ... | @@ -1141,8 +1141,8 @@ pub fn readElfDebugInfo( | ... | @@ -1141,8 +1141,8 @@ pub fn readElfDebugInfo( |
| 1141 | ) !ModuleDebugInfo { | 1141 | ) !ModuleDebugInfo { |
| 1142 | nosuspend { | 1142 | nosuspend { |
| 1143 | const elf_file = (if (elf_filename) |filename| blk: { | 1143 | const elf_file = (if (elf_filename) |filename| blk: { |
| 1144 | break :blk fs.cwd().openFile(filename, .{ .intended_io_mode = .blocking }); | 1144 | break :blk fs.cwd().openFile(filename, .{}); |
| 1145 | } else fs.openSelfExe(.{ .intended_io_mode = .blocking })) catch |err| switch (err) { | 1145 | } else fs.openSelfExe(.{})) catch |err| switch (err) { |
| 1146 | error.FileNotFound => return error.MissingDebugInfo, | 1146 | error.FileNotFound => return error.MissingDebugInfo, |
| 1147 | else => return err, | 1147 | else => return err, |
| 1148 | }; | 1148 | }; |
| ... | @@ -1452,7 +1452,7 @@ fn readMachODebugInfo(allocator: mem.Allocator, macho_file: File) !ModuleDebugIn | ... | @@ -1452,7 +1452,7 @@ fn readMachODebugInfo(allocator: mem.Allocator, macho_file: File) !ModuleDebugIn |
| 1452 | fn printLineFromFileAnyOs(out_stream: anytype, line_info: LineInfo) !void { | 1452 | fn printLineFromFileAnyOs(out_stream: anytype, line_info: LineInfo) !void { |
| 1453 | // Need this to always block even in async I/O mode, because this could potentially | 1453 | // Need this to always block even in async I/O mode, because this could potentially |
| 1454 | // be called from e.g. the event loop code crashing. | 1454 | // be called from e.g. the event loop code crashing. |
| 1455 | var f = try fs.cwd().openFile(line_info.file_name, .{ .intended_io_mode = .blocking }); | 1455 | var f = try fs.cwd().openFile(line_info.file_name, .{}); |
| 1456 | defer f.close(); | 1456 | defer f.close(); |
| 1457 | // TODO fstat and make sure that the file has the correct size | 1457 | // TODO fstat and make sure that the file has the correct size |
| 1458 | 1458 | ||
| ... | @@ -1640,7 +1640,6 @@ const MachoSymbol = struct { | ... | @@ -1640,7 +1640,6 @@ const MachoSymbol = struct { |
| 1640 | } | 1640 | } |
| 1641 | }; | 1641 | }; |
| 1642 | 1642 | ||
| 1643 | /// `file` is expected to have been opened with .intended_io_mode == .blocking. | ||
| 1644 | /// Takes ownership of file, even on error. | 1643 | /// Takes ownership of file, even on error. |
| 1645 | /// TODO it's weird to take ownership even on error, rework this code. | 1644 | /// TODO it's weird to take ownership even on error, rework this code. |
| 1646 | fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 { | 1645 | fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 { |
| ... | @@ -1824,9 +1823,7 @@ pub const DebugInfo = struct { | ... | @@ -1824,9 +1823,7 @@ pub const DebugInfo = struct { |
| 1824 | errdefer self.allocator.destroy(obj_di); | 1823 | errdefer self.allocator.destroy(obj_di); |
| 1825 | 1824 | ||
| 1826 | const macho_path = mem.sliceTo(std.c._dyld_get_image_name(i), 0); | 1825 | const macho_path = mem.sliceTo(std.c._dyld_get_image_name(i), 0); |
| 1827 | const macho_file = fs.cwd().openFile(macho_path, .{ | 1826 | const macho_file = fs.cwd().openFile(macho_path, .{}) catch |err| switch (err) { |
| 1828 | .intended_io_mode = .blocking, | ||
| 1829 | }) catch |err| switch (err) { | ||
| 1830 | error.FileNotFound => return error.MissingDebugInfo, | 1827 | error.FileNotFound => return error.MissingDebugInfo, |
| 1831 | else => return err, | 1828 | else => return err, |
| 1832 | }; | 1829 | }; |
| ... | @@ -2162,7 +2159,7 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -2162,7 +2159,7 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 2162 | } | 2159 | } |
| 2163 | 2160 | ||
| 2164 | fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !*OFileInfo { | 2161 | fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !*OFileInfo { |
| 2165 | const o_file = try fs.cwd().openFile(o_file_path, .{ .intended_io_mode = .blocking }); | 2162 | const o_file = try fs.cwd().openFile(o_file_path, .{}); |
| 2166 | const mapped_mem = try mapWholeFile(o_file); | 2163 | const mapped_mem = try mapWholeFile(o_file); |
| 2167 | 2164 | ||
| 2168 | const hdr: *const macho.mach_header_64 = @ptrCast(@alignCast(mapped_mem.ptr)); | 2165 | const hdr: *const macho.mach_header_64 = @ptrCast(@alignCast(mapped_mem.ptr)); |
lib/std/fs.zig-7| ... | @@ -84,13 +84,6 @@ pub const base64_encoder = base64.Base64Encoder.init(base64_alphabet, null); | ... | @@ -84,13 +84,6 @@ pub const base64_encoder = base64.Base64Encoder.init(base64_alphabet, null); |
| 84 | /// Base64 decoder, replacing the standard `+/` with `-_` so that it can be used in a file name on any filesystem. | 84 | /// Base64 decoder, replacing the standard `+/` with `-_` so that it can be used in a file name on any filesystem. |
| 85 | pub const base64_decoder = base64.Base64Decoder.init(base64_alphabet, null); | 85 | pub const base64_decoder = base64.Base64Decoder.init(base64_alphabet, null); |
| 86 | 86 | ||
| 87 | /// Whether or not async file system syscalls need a dedicated thread because the operating | ||
| 88 | /// system does not support non-blocking I/O on the file system. | ||
| 89 | pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) { | ||
| 90 | .windows, .other => false, | ||
| 91 | else => true, | ||
| 92 | }; | ||
| 93 | |||
| 94 | /// TODO remove the allocator requirement from this API | 87 | /// TODO remove the allocator requirement from this API |
| 95 | /// TODO move to Dir | 88 | /// TODO move to Dir |
| 96 | pub fn atomicSymLink(allocator: Allocator, existing_path: []const u8, new_path: []const u8) !void { | 89 | pub fn atomicSymLink(allocator: Allocator, existing_path: []const u8, new_path: []const u8) !void { |
lib/std/fs/Dir.zig+12-59| ... | @@ -751,11 +751,7 @@ pub const OpenError = error{ | ... | @@ -751,11 +751,7 @@ pub const OpenError = error{ |
| 751 | } || posix.UnexpectedError; | 751 | } || posix.UnexpectedError; |
| 752 | 752 | ||
| 753 | pub fn close(self: *Dir) void { | 753 | pub fn close(self: *Dir) void { |
| 754 | if (fs.need_async_thread) { | 754 | posix.close(self.fd); |
| 755 | std.event.Loop.instance.?.close(self.fd); | ||
| 756 | } else { | ||
| 757 | posix.close(self.fd); | ||
| 758 | } | ||
| 759 | self.* = undefined; | 755 | self.* = undefined; |
| 760 | } | 756 | } |
| 761 | 757 | ||
| ... | @@ -837,10 +833,7 @@ pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File | ... | @@ -837,10 +833,7 @@ pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File |
| 837 | .write_only => @as(u32, posix.O.WRONLY), | 833 | .write_only => @as(u32, posix.O.WRONLY), |
| 838 | .read_write => @as(u32, posix.O.RDWR), | 834 | .read_write => @as(u32, posix.O.RDWR), |
| 839 | }; | 835 | }; |
| 840 | const fd = if (flags.intended_io_mode != .blocking) | 836 | const fd = try posix.openatZ(self.fd, sub_path, os_flags, 0); |
| 841 | try std.event.Loop.instance.?.openatZ(self.fd, sub_path, os_flags, 0) | ||
| 842 | else | ||
| 843 | try posix.openatZ(self.fd, sub_path, os_flags, 0); | ||
| 844 | errdefer posix.close(fd); | 837 | errdefer posix.close(fd); |
| 845 | 838 | ||
| 846 | // WASI doesn't have posix.flock so we intetinally check OS prior to the inner if block | 839 | // WASI doesn't have posix.flock so we intetinally check OS prior to the inner if block |
| ... | @@ -877,11 +870,7 @@ pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File | ... | @@ -877,11 +870,7 @@ pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File |
| 877 | }; | 870 | }; |
| 878 | } | 871 | } |
| 879 | 872 | ||
| 880 | return File{ | 873 | return File{ .handle = fd }; |
| 881 | .handle = fd, | ||
| 882 | .capable_io_mode = .blocking, | ||
| 883 | .intended_io_mode = flags.intended_io_mode, | ||
| 884 | }; | ||
| 885 | } | 874 | } |
| 886 | 875 | ||
| 887 | /// Same as `openFile` but Windows-only and the path parameter is | 876 | /// Same as `openFile` but Windows-only and the path parameter is |
| ... | @@ -895,10 +884,7 @@ pub fn openFileW(self: Dir, sub_path_w: []const u16, flags: File.OpenFlags) File | ... | @@ -895,10 +884,7 @@ pub fn openFileW(self: Dir, sub_path_w: []const u16, flags: File.OpenFlags) File |
| 895 | (if (flags.isRead()) @as(u32, w.GENERIC_READ) else 0) | | 884 | (if (flags.isRead()) @as(u32, w.GENERIC_READ) else 0) | |
| 896 | (if (flags.isWrite()) @as(u32, w.GENERIC_WRITE) else 0), | 885 | (if (flags.isWrite()) @as(u32, w.GENERIC_WRITE) else 0), |
| 897 | .creation = w.FILE_OPEN, | 886 | .creation = w.FILE_OPEN, |
| 898 | .io_mode = flags.intended_io_mode, | ||
| 899 | }), | 887 | }), |
| 900 | .capable_io_mode = std.io.default_mode, | ||
| 901 | .intended_io_mode = flags.intended_io_mode, | ||
| 902 | }; | 888 | }; |
| 903 | errdefer file.close(); | 889 | errdefer file.close(); |
| 904 | var io: w.IO_STATUS_BLOCK = undefined; | 890 | var io: w.IO_STATUS_BLOCK = undefined; |
| ... | @@ -994,10 +980,7 @@ pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags | ... | @@ -994,10 +980,7 @@ pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags |
| 994 | (if (flags.truncate) @as(u32, posix.O.TRUNC) else 0) | | 980 | (if (flags.truncate) @as(u32, posix.O.TRUNC) else 0) | |
| 995 | (if (flags.read) @as(u32, posix.O.RDWR) else posix.O.WRONLY) | | 981 | (if (flags.read) @as(u32, posix.O.RDWR) else posix.O.WRONLY) | |
| 996 | (if (flags.exclusive) @as(u32, posix.O.EXCL) else 0); | 982 | (if (flags.exclusive) @as(u32, posix.O.EXCL) else 0); |
| 997 | const fd = if (flags.intended_io_mode != .blocking) | 983 | const fd = try posix.openatZ(self.fd, sub_path_c, os_flags, flags.mode); |
| 998 | try std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, os_flags, flags.mode) | ||
| 999 | else | ||
| 1000 | try posix.openatZ(self.fd, sub_path_c, os_flags, flags.mode); | ||
| 1001 | errdefer posix.close(fd); | 984 | errdefer posix.close(fd); |
| 1002 | 985 | ||
| 1003 | // WASI doesn't have posix.flock so we intetinally check OS prior to the inner if block | 986 | // WASI doesn't have posix.flock so we intetinally check OS prior to the inner if block |
| ... | @@ -1034,11 +1017,7 @@ pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags | ... | @@ -1034,11 +1017,7 @@ pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags |
| 1034 | }; | 1017 | }; |
| 1035 | } | 1018 | } |
| 1036 | 1019 | ||
| 1037 | return File{ | 1020 | return File{ .handle = fd }; |
| 1038 | .handle = fd, | ||
| 1039 | .capable_io_mode = .blocking, | ||
| 1040 | .intended_io_mode = flags.intended_io_mode, | ||
| 1041 | }; | ||
| 1042 | } | 1021 | } |
| 1043 | 1022 | ||
| 1044 | /// Same as `createFile` but Windows-only and the path parameter is | 1023 | /// Same as `createFile` but Windows-only and the path parameter is |
| ... | @@ -1056,10 +1035,7 @@ pub fn createFileW(self: Dir, sub_path_w: []const u16, flags: File.CreateFlags) | ... | @@ -1056,10 +1035,7 @@ pub fn createFileW(self: Dir, sub_path_w: []const u16, flags: File.CreateFlags) |
| 1056 | @as(u32, w.FILE_OVERWRITE_IF) | 1035 | @as(u32, w.FILE_OVERWRITE_IF) |
| 1057 | else | 1036 | else |
| 1058 | @as(u32, w.FILE_OPEN_IF), | 1037 | @as(u32, w.FILE_OPEN_IF), |
| 1059 | .io_mode = flags.intended_io_mode, | ||
| 1060 | }), | 1038 | }), |
| 1061 | .capable_io_mode = std.io.default_mode, | ||
| 1062 | .intended_io_mode = flags.intended_io_mode, | ||
| 1063 | }; | 1039 | }; |
| 1064 | errdefer file.close(); | 1040 | errdefer file.close(); |
| 1065 | var io: w.IO_STATUS_BLOCK = undefined; | 1041 | var io: w.IO_STATUS_BLOCK = undefined; |
| ... | @@ -1276,7 +1252,6 @@ pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) ![]u8 { | ... | @@ -1276,7 +1252,6 @@ pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) ![]u8 { |
| 1276 | .access_mask = access_mask, | 1252 | .access_mask = access_mask, |
| 1277 | .share_access = share_access, | 1253 | .share_access = share_access, |
| 1278 | .creation = creation, | 1254 | .creation = creation, |
| 1279 | .io_mode = .blocking, | ||
| 1280 | .filter = .any, | 1255 | .filter = .any, |
| 1281 | }) catch |err| switch (err) { | 1256 | }) catch |err| switch (err) { |
| 1282 | error.WouldBlock => unreachable, | 1257 | error.WouldBlock => unreachable, |
| ... | @@ -1449,11 +1424,7 @@ pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16, args: OpenDirOptions) Ope | ... | @@ -1449,11 +1424,7 @@ pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16, args: OpenDirOptions) Ope |
| 1449 | 1424 | ||
| 1450 | /// `flags` must contain `posix.O.DIRECTORY`. | 1425 | /// `flags` must contain `posix.O.DIRECTORY`. |
| 1451 | fn openDirFlagsZ(self: Dir, sub_path_c: [*:0]const u8, flags: u32) OpenError!Dir { | 1426 | fn openDirFlagsZ(self: Dir, sub_path_c: [*:0]const u8, flags: u32) OpenError!Dir { |
| 1452 | const result = if (fs.need_async_thread) | 1427 | const fd = posix.openatZ(self.fd, sub_path_c, flags, 0) catch |err| switch (err) { |
| 1453 | std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, flags, 0) | ||
| 1454 | else | ||
| 1455 | posix.openatZ(self.fd, sub_path_c, flags, 0); | ||
| 1456 | const fd = result catch |err| switch (err) { | ||
| 1457 | error.FileTooBig => unreachable, // can't happen for directories | 1428 | error.FileTooBig => unreachable, // can't happen for directories |
| 1458 | error.IsDir => unreachable, // we're providing O.DIRECTORY | 1429 | error.IsDir => unreachable, // we're providing O.DIRECTORY |
| 1459 | error.NoSpaceLeft => unreachable, // not providing O.CREAT | 1430 | error.NoSpaceLeft => unreachable, // not providing O.CREAT |
| ... | @@ -2270,10 +2241,7 @@ pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) Access | ... | @@ -2270,10 +2241,7 @@ pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) Access |
| 2270 | .write_only => @as(u32, posix.W_OK), | 2241 | .write_only => @as(u32, posix.W_OK), |
| 2271 | .read_write => @as(u32, posix.R_OK | posix.W_OK), | 2242 | .read_write => @as(u32, posix.R_OK | posix.W_OK), |
| 2272 | }; | 2243 | }; |
| 2273 | const result = if (fs.need_async_thread and flags.intended_io_mode != .blocking) | 2244 | const result = posix.faccessatZ(self.fd, sub_path, os_mode, 0); |
| 2274 | std.event.Loop.instance.?.faccessatZ(self.fd, sub_path, os_mode, 0) | ||
| 2275 | else | ||
| 2276 | posix.faccessatZ(self.fd, sub_path, os_mode, 0); | ||
| 2277 | return result; | 2245 | return result; |
| 2278 | } | 2246 | } |
| 2279 | 2247 | ||
| ... | @@ -2457,10 +2425,7 @@ pub const Stat = File.Stat; | ... | @@ -2457,10 +2425,7 @@ pub const Stat = File.Stat; |
| 2457 | pub const StatError = File.StatError; | 2425 | pub const StatError = File.StatError; |
| 2458 | 2426 | ||
| 2459 | pub fn stat(self: Dir) StatError!Stat { | 2427 | pub fn stat(self: Dir) StatError!Stat { |
| 2460 | const file: File = .{ | 2428 | const file: File = .{ .handle = self.fd }; |
| 2461 | .handle = self.fd, | ||
| 2462 | .capable_io_mode = .blocking, | ||
| 2463 | }; | ||
| 2464 | return file.stat(); | 2429 | return file.stat(); |
| 2465 | } | 2430 | } |
| 2466 | 2431 | ||
| ... | @@ -2496,10 +2461,7 @@ pub const ChmodError = File.ChmodError; | ... | @@ -2496,10 +2461,7 @@ pub const ChmodError = File.ChmodError; |
| 2496 | /// of the directory. Additionally, the directory must have been opened | 2461 | /// of the directory. Additionally, the directory must have been opened |
| 2497 | /// with `OpenDirOptions{ .iterate = true }`. | 2462 | /// with `OpenDirOptions{ .iterate = true }`. |
| 2498 | pub fn chmod(self: Dir, new_mode: File.Mode) ChmodError!void { | 2463 | pub fn chmod(self: Dir, new_mode: File.Mode) ChmodError!void { |
| 2499 | const file: File = .{ | 2464 | const file: File = .{ .handle = self.fd }; |
| 2500 | .handle = self.fd, | ||
| 2501 | .capable_io_mode = .blocking, | ||
| 2502 | }; | ||
| 2503 | try file.chmod(new_mode); | 2465 | try file.chmod(new_mode); |
| 2504 | } | 2466 | } |
| 2505 | 2467 | ||
| ... | @@ -2510,10 +2472,7 @@ pub fn chmod(self: Dir, new_mode: File.Mode) ChmodError!void { | ... | @@ -2510,10 +2472,7 @@ pub fn chmod(self: Dir, new_mode: File.Mode) ChmodError!void { |
| 2510 | /// must have been opened with `OpenDirOptions{ .iterate = true }`. If the | 2472 | /// must have been opened with `OpenDirOptions{ .iterate = true }`. If the |
| 2511 | /// owner or group is specified as `null`, the ID is not changed. | 2473 | /// owner or group is specified as `null`, the ID is not changed. |
| 2512 | pub fn chown(self: Dir, owner: ?File.Uid, group: ?File.Gid) ChownError!void { | 2474 | pub fn chown(self: Dir, owner: ?File.Uid, group: ?File.Gid) ChownError!void { |
| 2513 | const file: File = .{ | 2475 | const file: File = .{ .handle = self.fd }; |
| 2514 | .handle = self.fd, | ||
| 2515 | .capable_io_mode = .blocking, | ||
| 2516 | }; | ||
| 2517 | try file.chown(owner, group); | 2476 | try file.chown(owner, group); |
| 2518 | } | 2477 | } |
| 2519 | 2478 | ||
| ... | @@ -2525,10 +2484,7 @@ pub const SetPermissionsError = File.SetPermissionsError; | ... | @@ -2525,10 +2484,7 @@ pub const SetPermissionsError = File.SetPermissionsError; |
| 2525 | /// Sets permissions according to the provided `Permissions` struct. | 2484 | /// Sets permissions according to the provided `Permissions` struct. |
| 2526 | /// This method is *NOT* available on WASI | 2485 | /// This method is *NOT* available on WASI |
| 2527 | pub fn setPermissions(self: Dir, permissions: Permissions) SetPermissionsError!void { | 2486 | pub fn setPermissions(self: Dir, permissions: Permissions) SetPermissionsError!void { |
| 2528 | const file: File = .{ | 2487 | const file: File = .{ .handle = self.fd }; |
| 2529 | .handle = self.fd, | ||
| 2530 | .capable_io_mode = .blocking, | ||
| 2531 | }; | ||
| 2532 | try file.setPermissions(permissions); | 2488 | try file.setPermissions(permissions); |
| 2533 | } | 2489 | } |
| 2534 | 2490 | ||
| ... | @@ -2537,10 +2493,7 @@ pub const MetadataError = File.MetadataError; | ... | @@ -2537,10 +2493,7 @@ pub const MetadataError = File.MetadataError; |
| 2537 | 2493 | ||
| 2538 | /// Returns a `Metadata` struct, representing the permissions on the directory | 2494 | /// Returns a `Metadata` struct, representing the permissions on the directory |
| 2539 | pub fn metadata(self: Dir) MetadataError!Metadata { | 2495 | pub fn metadata(self: Dir) MetadataError!Metadata { |
| 2540 | const file: File = .{ | 2496 | const file: File = .{ .handle = self.fd }; |
| 2541 | .handle = self.fd, | ||
| 2542 | .capable_io_mode = .blocking, | ||
| 2543 | }; | ||
| 2544 | return try file.metadata(); | 2497 | return try file.metadata(); |
| 2545 | } | 2498 | } |
| 2546 | 2499 |
lib/std/fs/File.zig+16-80| ... | @@ -1,20 +1,6 @@ | ... | @@ -1,20 +1,6 @@ |
| 1 | /// The OS-specific file descriptor or file handle. | 1 | /// The OS-specific file descriptor or file handle. |
| 2 | handle: Handle, | 2 | handle: Handle, |
| 3 | 3 | ||
| 4 | /// On some systems, such as Linux, file system file descriptors are incapable | ||
| 5 | /// of non-blocking I/O. This forces us to perform asynchronous I/O on a dedicated thread, | ||
| 6 | /// to achieve non-blocking file-system I/O. To do this, `File` must be aware of whether | ||
| 7 | /// it is a file system file descriptor, or, more specifically, whether the I/O is always | ||
| 8 | /// blocking. | ||
| 9 | capable_io_mode: io.ModeOverride = io.default_mode, | ||
| 10 | |||
| 11 | /// Furthermore, even when `std.options.io_mode` is async, it is still sometimes desirable | ||
| 12 | /// to perform blocking I/O, although not by default. For example, when printing a | ||
| 13 | /// stack trace to stderr. This field tracks both by acting as an overriding I/O mode. | ||
| 14 | /// When not building in async I/O mode, the type only has the `.blocking` tag, making | ||
| 15 | /// it a zero-bit type. | ||
| 16 | intended_io_mode: io.ModeOverride = io.default_mode, | ||
| 17 | |||
| 18 | pub const Handle = posix.fd_t; | 4 | pub const Handle = posix.fd_t; |
| 19 | pub const Mode = posix.mode_t; | 5 | pub const Mode = posix.mode_t; |
| 20 | pub const INode = posix.ino_t; | 6 | pub const INode = posix.ino_t; |
| ... | @@ -108,16 +94,8 @@ pub const OpenFlags = struct { | ... | @@ -108,16 +94,8 @@ pub const OpenFlags = struct { |
| 108 | /// Sets whether or not to wait until the file is locked to return. If set to true, | 94 | /// Sets whether or not to wait until the file is locked to return. If set to true, |
| 109 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file | 95 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file |
| 110 | /// is available to proceed. | 96 | /// is available to proceed. |
| 111 | /// In async I/O mode, non-blocking at the OS level is | ||
| 112 | /// determined by `intended_io_mode`, and `true` means `error.WouldBlock` is returned, | ||
| 113 | /// and `false` means `error.WouldBlock` is handled by the event loop. | ||
| 114 | lock_nonblocking: bool = false, | 97 | lock_nonblocking: bool = false, |
| 115 | 98 | ||
| 116 | /// Setting this to `.blocking` prevents `O.NONBLOCK` from being passed even | ||
| 117 | /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions | ||
| 118 | /// related to opening the file, reading, writing, and locking. | ||
| 119 | intended_io_mode: io.ModeOverride = io.default_mode, | ||
| 120 | |||
| 121 | /// Set this to allow the opened file to automatically become the | 99 | /// Set this to allow the opened file to automatically become the |
| 122 | /// controlling TTY for the current process. | 100 | /// controlling TTY for the current process. |
| 123 | allow_ctty: bool = false, | 101 | allow_ctty: bool = false, |
| ... | @@ -172,19 +150,11 @@ pub const CreateFlags = struct { | ... | @@ -172,19 +150,11 @@ pub const CreateFlags = struct { |
| 172 | /// Sets whether or not to wait until the file is locked to return. If set to true, | 150 | /// Sets whether or not to wait until the file is locked to return. If set to true, |
| 173 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file | 151 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file |
| 174 | /// is available to proceed. | 152 | /// is available to proceed. |
| 175 | /// In async I/O mode, non-blocking at the OS level is | ||
| 176 | /// determined by `intended_io_mode`, and `true` means `error.WouldBlock` is returned, | ||
| 177 | /// and `false` means `error.WouldBlock` is handled by the event loop. | ||
| 178 | lock_nonblocking: bool = false, | 153 | lock_nonblocking: bool = false, |
| 179 | 154 | ||
| 180 | /// For POSIX systems this is the file system mode the file will | 155 | /// For POSIX systems this is the file system mode the file will |
| 181 | /// be created with. On other systems this is always 0. | 156 | /// be created with. On other systems this is always 0. |
| 182 | mode: Mode = default_mode, | 157 | mode: Mode = default_mode, |
| 183 | |||
| 184 | /// Setting this to `.blocking` prevents `O.NONBLOCK` from being passed even | ||
| 185 | /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions | ||
| 186 | /// related to opening the file, reading, writing, and locking. | ||
| 187 | intended_io_mode: io.ModeOverride = io.default_mode, | ||
| 188 | }; | 158 | }; |
| 189 | 159 | ||
| 190 | /// Upon success, the stream is in an uninitialized state. To continue using it, | 160 | /// Upon success, the stream is in an uninitialized state. To continue using it, |
| ... | @@ -192,8 +162,6 @@ pub const CreateFlags = struct { | ... | @@ -192,8 +162,6 @@ pub const CreateFlags = struct { |
| 192 | pub fn close(self: File) void { | 162 | pub fn close(self: File) void { |
| 193 | if (is_windows) { | 163 | if (is_windows) { |
| 194 | windows.CloseHandle(self.handle); | 164 | windows.CloseHandle(self.handle); |
| 195 | } else if (self.capable_io_mode != self.intended_io_mode) { | ||
| 196 | std.event.Loop.instance.?.close(self.handle); | ||
| 197 | } else { | 165 | } else { |
| 198 | posix.close(self.handle); | 166 | posix.close(self.handle); |
| 199 | } | 167 | } |
| ... | @@ -1013,14 +981,10 @@ pub const PReadError = posix.PReadError; | ... | @@ -1013,14 +981,10 @@ pub const PReadError = posix.PReadError; |
| 1013 | 981 | ||
| 1014 | pub fn read(self: File, buffer: []u8) ReadError!usize { | 982 | pub fn read(self: File, buffer: []u8) ReadError!usize { |
| 1015 | if (is_windows) { | 983 | if (is_windows) { |
| 1016 | return windows.ReadFile(self.handle, buffer, null, self.intended_io_mode); | 984 | return windows.ReadFile(self.handle, buffer, null); |
| 1017 | } | 985 | } |
| 1018 | 986 | ||
| 1019 | if (self.intended_io_mode == .blocking) { | 987 | return posix.read(self.handle, buffer); |
| 1020 | return posix.read(self.handle, buffer); | ||
| 1021 | } else { | ||
| 1022 | return std.event.Loop.instance.?.read(self.handle, buffer, self.capable_io_mode != self.intended_io_mode); | ||
| 1023 | } | ||
| 1024 | } | 988 | } |
| 1025 | 989 | ||
| 1026 | /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it | 990 | /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it |
| ... | @@ -1039,14 +1003,10 @@ pub fn readAll(self: File, buffer: []u8) ReadError!usize { | ... | @@ -1039,14 +1003,10 @@ pub fn readAll(self: File, buffer: []u8) ReadError!usize { |
| 1039 | /// https://github.com/ziglang/zig/issues/12783 | 1003 | /// https://github.com/ziglang/zig/issues/12783 |
| 1040 | pub fn pread(self: File, buffer: []u8, offset: u64) PReadError!usize { | 1004 | pub fn pread(self: File, buffer: []u8, offset: u64) PReadError!usize { |
| 1041 | if (is_windows) { | 1005 | if (is_windows) { |
| 1042 | return windows.ReadFile(self.handle, buffer, offset, self.intended_io_mode); | 1006 | return windows.ReadFile(self.handle, buffer, offset); |
| 1043 | } | 1007 | } |
| 1044 | 1008 | ||
| 1045 | if (self.intended_io_mode == .blocking) { | 1009 | return posix.pread(self.handle, buffer, offset); |
| 1046 | return posix.pread(self.handle, buffer, offset); | ||
| 1047 | } else { | ||
| 1048 | return std.event.Loop.instance.?.pread(self.handle, buffer, offset, self.capable_io_mode != self.intended_io_mode); | ||
| 1049 | } | ||
| 1050 | } | 1010 | } |
| 1051 | 1011 | ||
| 1052 | /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it | 1012 | /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it |
| ... | @@ -1069,14 +1029,10 @@ pub fn readv(self: File, iovecs: []const posix.iovec) ReadError!usize { | ... | @@ -1069,14 +1029,10 @@ pub fn readv(self: File, iovecs: []const posix.iovec) ReadError!usize { |
| 1069 | // TODO improve this to use ReadFileScatter | 1029 | // TODO improve this to use ReadFileScatter |
| 1070 | if (iovecs.len == 0) return @as(usize, 0); | 1030 | if (iovecs.len == 0) return @as(usize, 0); |
| 1071 | const first = iovecs[0]; | 1031 | const first = iovecs[0]; |
| 1072 | return windows.ReadFile(self.handle, first.iov_base[0..first.iov_len], null, self.intended_io_mode); | 1032 | return windows.ReadFile(self.handle, first.iov_base[0..first.iov_len], null); |
| 1073 | } | 1033 | } |
| 1074 | 1034 | ||
| 1075 | if (self.intended_io_mode == .blocking) { | 1035 | return posix.readv(self.handle, iovecs); |
| 1076 | return posix.readv(self.handle, iovecs); | ||
| 1077 | } else { | ||
| 1078 | return std.event.Loop.instance.?.readv(self.handle, iovecs, self.capable_io_mode != self.intended_io_mode); | ||
| 1079 | } | ||
| 1080 | } | 1036 | } |
| 1081 | 1037 | ||
| 1082 | /// Returns the number of bytes read. If the number read is smaller than the total bytes | 1038 | /// Returns the number of bytes read. If the number read is smaller than the total bytes |
| ... | @@ -1129,14 +1085,10 @@ pub fn preadv(self: File, iovecs: []const posix.iovec, offset: u64) PReadError!u | ... | @@ -1129,14 +1085,10 @@ pub fn preadv(self: File, iovecs: []const posix.iovec, offset: u64) PReadError!u |
| 1129 | // TODO improve this to use ReadFileScatter | 1085 | // TODO improve this to use ReadFileScatter |
| 1130 | if (iovecs.len == 0) return @as(usize, 0); | 1086 | if (iovecs.len == 0) return @as(usize, 0); |
| 1131 | const first = iovecs[0]; | 1087 | const first = iovecs[0]; |
| 1132 | return windows.ReadFile(self.handle, first.iov_base[0..first.iov_len], offset, self.intended_io_mode); | 1088 | return windows.ReadFile(self.handle, first.iov_base[0..first.iov_len], offset); |
| 1133 | } | 1089 | } |
| 1134 | 1090 | ||
| 1135 | if (self.intended_io_mode == .blocking) { | 1091 | return posix.preadv(self.handle, iovecs, offset); |
| 1136 | return posix.preadv(self.handle, iovecs, offset); | ||
| 1137 | } else { | ||
| 1138 | return std.event.Loop.instance.?.preadv(self.handle, iovecs, offset, self.capable_io_mode != self.intended_io_mode); | ||
| 1139 | } | ||
| 1140 | } | 1092 | } |
| 1141 | 1093 | ||
| 1142 | /// Returns the number of bytes read. If the number read is smaller than the total bytes | 1094 | /// Returns the number of bytes read. If the number read is smaller than the total bytes |
| ... | @@ -1173,14 +1125,10 @@ pub const PWriteError = posix.PWriteError; | ... | @@ -1173,14 +1125,10 @@ pub const PWriteError = posix.PWriteError; |
| 1173 | 1125 | ||
| 1174 | pub fn write(self: File, bytes: []const u8) WriteError!usize { | 1126 | pub fn write(self: File, bytes: []const u8) WriteError!usize { |
| 1175 | if (is_windows) { | 1127 | if (is_windows) { |
| 1176 | return windows.WriteFile(self.handle, bytes, null, self.intended_io_mode); | 1128 | return windows.WriteFile(self.handle, bytes, null); |
| 1177 | } | 1129 | } |
| 1178 | 1130 | ||
| 1179 | if (self.intended_io_mode == .blocking) { | 1131 | return posix.write(self.handle, bytes); |
| 1180 | return posix.write(self.handle, bytes); | ||
| 1181 | } else { | ||
| 1182 | return std.event.Loop.instance.?.write(self.handle, bytes, self.capable_io_mode != self.intended_io_mode); | ||
| 1183 | } | ||
| 1184 | } | 1132 | } |
| 1185 | 1133 | ||
| 1186 | pub fn writeAll(self: File, bytes: []const u8) WriteError!void { | 1134 | pub fn writeAll(self: File, bytes: []const u8) WriteError!void { |
| ... | @@ -1194,14 +1142,10 @@ pub fn writeAll(self: File, bytes: []const u8) WriteError!void { | ... | @@ -1194,14 +1142,10 @@ pub fn writeAll(self: File, bytes: []const u8) WriteError!void { |
| 1194 | /// https://github.com/ziglang/zig/issues/12783 | 1142 | /// https://github.com/ziglang/zig/issues/12783 |
| 1195 | pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize { | 1143 | pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize { |
| 1196 | if (is_windows) { | 1144 | if (is_windows) { |
| 1197 | return windows.WriteFile(self.handle, bytes, offset, self.intended_io_mode); | 1145 | return windows.WriteFile(self.handle, bytes, offset); |
| 1198 | } | 1146 | } |
| 1199 | 1147 | ||
| 1200 | if (self.intended_io_mode == .blocking) { | 1148 | return posix.pwrite(self.handle, bytes, offset); |
| 1201 | return posix.pwrite(self.handle, bytes, offset); | ||
| 1202 | } else { | ||
| 1203 | return std.event.Loop.instance.?.pwrite(self.handle, bytes, offset, self.capable_io_mode != self.intended_io_mode); | ||
| 1204 | } | ||
| 1205 | } | 1149 | } |
| 1206 | 1150 | ||
| 1207 | /// On Windows, this function currently does alter the file pointer. | 1151 | /// On Windows, this function currently does alter the file pointer. |
| ... | @@ -1220,14 +1164,10 @@ pub fn writev(self: File, iovecs: []const posix.iovec_const) WriteError!usize { | ... | @@ -1220,14 +1164,10 @@ pub fn writev(self: File, iovecs: []const posix.iovec_const) WriteError!usize { |
| 1220 | // TODO improve this to use WriteFileScatter | 1164 | // TODO improve this to use WriteFileScatter |
| 1221 | if (iovecs.len == 0) return @as(usize, 0); | 1165 | if (iovecs.len == 0) return @as(usize, 0); |
| 1222 | const first = iovecs[0]; | 1166 | const first = iovecs[0]; |
| 1223 | return windows.WriteFile(self.handle, first.iov_base[0..first.iov_len], null, self.intended_io_mode); | 1167 | return windows.WriteFile(self.handle, first.iov_base[0..first.iov_len], null); |
| 1224 | } | 1168 | } |
| 1225 | 1169 | ||
| 1226 | if (self.intended_io_mode == .blocking) { | 1170 | return posix.writev(self.handle, iovecs); |
| 1227 | return posix.writev(self.handle, iovecs); | ||
| 1228 | } else { | ||
| 1229 | return std.event.Loop.instance.?.writev(self.handle, iovecs, self.capable_io_mode != self.intended_io_mode); | ||
| 1230 | } | ||
| 1231 | } | 1171 | } |
| 1232 | 1172 | ||
| 1233 | /// The `iovecs` parameter is mutable because: | 1173 | /// The `iovecs` parameter is mutable because: |
| ... | @@ -1271,14 +1211,10 @@ pub fn pwritev(self: File, iovecs: []posix.iovec_const, offset: u64) PWriteError | ... | @@ -1271,14 +1211,10 @@ pub fn pwritev(self: File, iovecs: []posix.iovec_const, offset: u64) PWriteError |
| 1271 | // TODO improve this to use WriteFileScatter | 1211 | // TODO improve this to use WriteFileScatter |
| 1272 | if (iovecs.len == 0) return @as(usize, 0); | 1212 | if (iovecs.len == 0) return @as(usize, 0); |
| 1273 | const first = iovecs[0]; | 1213 | const first = iovecs[0]; |
| 1274 | return windows.WriteFile(self.handle, first.iov_base[0..first.iov_len], offset, self.intended_io_mode); | 1214 | return windows.WriteFile(self.handle, first.iov_base[0..first.iov_len], offset); |
| 1275 | } | 1215 | } |
| 1276 | 1216 | ||
| 1277 | if (self.intended_io_mode == .blocking) { | 1217 | return posix.pwritev(self.handle, iovecs, offset); |
| 1278 | return posix.pwritev(self.handle, iovecs, offset); | ||
| 1279 | } else { | ||
| 1280 | return std.event.Loop.instance.?.pwritev(self.handle, iovecs, offset, self.capable_io_mode != self.intended_io_mode); | ||
| 1281 | } | ||
| 1282 | } | 1218 | } |
| 1283 | 1219 | ||
| 1284 | /// The `iovecs` parameter is mutable because this function needs to mutate the fields in | 1220 | /// The `iovecs` parameter is mutable because this function needs to mutate the fields in |
lib/std/fs/test.zig-5| ... | @@ -1508,11 +1508,6 @@ test "open file with exclusive and shared nonblocking lock" { | ... | @@ -1508,11 +1508,6 @@ test "open file with exclusive and shared nonblocking lock" { |
| 1508 | test "open file with exclusive lock twice, make sure second lock waits" { | 1508 | test "open file with exclusive lock twice, make sure second lock waits" { |
| 1509 | if (builtin.single_threaded) return error.SkipZigTest; | 1509 | if (builtin.single_threaded) return error.SkipZigTest; |
| 1510 | 1510 | ||
| 1511 | if (std.io.is_async) { | ||
| 1512 | // This test starts its own threads and is not compatible with async I/O. | ||
| 1513 | return error.SkipZigTest; | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | try testWithAllSupportedPathTypes(struct { | 1511 | try testWithAllSupportedPathTypes(struct { |
| 1517 | fn impl(ctx: *TestContext) !void { | 1512 | fn impl(ctx: *TestContext) !void { |
| 1518 | const filename = try ctx.transformPath("file_lock_test.txt"); | 1513 | const filename = try ctx.transformPath("file_lock_test.txt"); |
lib/std/io.zig+3-36| ... | @@ -12,21 +12,6 @@ const meta = std.meta; | ... | @@ -12,21 +12,6 @@ const meta = std.meta; |
| 12 | const File = std.fs.File; | 12 | const File = std.fs.File; |
| 13 | const Allocator = std.mem.Allocator; | 13 | const Allocator = std.mem.Allocator; |
| 14 | 14 | ||
| 15 | pub const Mode = enum { | ||
| 16 | /// I/O operates normally, waiting for the operating system syscalls to complete. | ||
| 17 | blocking, | ||
| 18 | |||
| 19 | /// I/O functions are generated async and rely on a global event loop. Event-based I/O. | ||
| 20 | evented, | ||
| 21 | }; | ||
| 22 | |||
| 23 | pub const is_async = false; | ||
| 24 | |||
| 25 | /// This is an enum value to use for I/O mode at runtime, since it takes up zero bytes at runtime, | ||
| 26 | /// and makes expressions comptime-known when `is_async` is `false`. | ||
| 27 | pub const ModeOverride = if (is_async) Mode else enum { blocking }; | ||
| 28 | pub const default_mode: ModeOverride = if (is_async) Mode.evented else .blocking; | ||
| 29 | |||
| 30 | fn getStdOutHandle() os.fd_t { | 15 | fn getStdOutHandle() os.fd_t { |
| 31 | if (builtin.os.tag == .windows) { | 16 | if (builtin.os.tag == .windows) { |
| 32 | if (builtin.zig_backend == .stage2_aarch64) { | 17 | if (builtin.zig_backend == .stage2_aarch64) { |
| ... | @@ -43,14 +28,8 @@ fn getStdOutHandle() os.fd_t { | ... | @@ -43,14 +28,8 @@ fn getStdOutHandle() os.fd_t { |
| 43 | return os.STDOUT_FILENO; | 28 | return os.STDOUT_FILENO; |
| 44 | } | 29 | } |
| 45 | 30 | ||
| 46 | /// TODO: async stdout on windows without a dedicated thread. | ||
| 47 | /// https://github.com/ziglang/zig/pull/4816#issuecomment-604521023 | ||
| 48 | pub fn getStdOut() File { | 31 | pub fn getStdOut() File { |
| 49 | return File{ | 32 | return File{ .handle = getStdOutHandle() }; |
| 50 | .handle = getStdOutHandle(), | ||
| 51 | .capable_io_mode = .blocking, | ||
| 52 | .intended_io_mode = default_mode, | ||
| 53 | }; | ||
| 54 | } | 33 | } |
| 55 | 34 | ||
| 56 | fn getStdErrHandle() os.fd_t { | 35 | fn getStdErrHandle() os.fd_t { |
| ... | @@ -69,14 +48,8 @@ fn getStdErrHandle() os.fd_t { | ... | @@ -69,14 +48,8 @@ fn getStdErrHandle() os.fd_t { |
| 69 | return os.STDERR_FILENO; | 48 | return os.STDERR_FILENO; |
| 70 | } | 49 | } |
| 71 | 50 | ||
| 72 | /// This returns a `File` that is configured to block with every write, in order | ||
| 73 | /// to facilitate better debugging. This can be changed by modifying the `intended_io_mode` field. | ||
| 74 | pub fn getStdErr() File { | 51 | pub fn getStdErr() File { |
| 75 | return File{ | 52 | return File{ .handle = getStdErrHandle() }; |
| 76 | .handle = getStdErrHandle(), | ||
| 77 | .capable_io_mode = .blocking, | ||
| 78 | .intended_io_mode = .blocking, | ||
| 79 | }; | ||
| 80 | } | 53 | } |
| 81 | 54 | ||
| 82 | fn getStdInHandle() os.fd_t { | 55 | fn getStdInHandle() os.fd_t { |
| ... | @@ -95,14 +68,8 @@ fn getStdInHandle() os.fd_t { | ... | @@ -95,14 +68,8 @@ fn getStdInHandle() os.fd_t { |
| 95 | return os.STDIN_FILENO; | 68 | return os.STDIN_FILENO; |
| 96 | } | 69 | } |
| 97 | 70 | ||
| 98 | /// TODO: async stdin on windows without a dedicated thread. | ||
| 99 | /// https://github.com/ziglang/zig/pull/4816#issuecomment-604521023 | ||
| 100 | pub fn getStdIn() File { | 71 | pub fn getStdIn() File { |
| 101 | return File{ | 72 | return File{ .handle = getStdInHandle() }; |
| 102 | .handle = getStdInHandle(), | ||
| 103 | .capable_io_mode = .blocking, | ||
| 104 | .intended_io_mode = default_mode, | ||
| 105 | }; | ||
| 106 | } | 73 | } |
| 107 | 74 | ||
| 108 | pub fn GenericReader( | 75 | pub fn GenericReader( |
lib/std/net.zig+16-63| ... | @@ -651,7 +651,7 @@ pub const Ip6Address = extern struct { | ... | @@ -651,7 +651,7 @@ pub const Ip6Address = extern struct { |
| 651 | }; | 651 | }; |
| 652 | 652 | ||
| 653 | pub fn connectUnixSocket(path: []const u8) !Stream { | 653 | pub fn connectUnixSocket(path: []const u8) !Stream { |
| 654 | const opt_non_block = if (std.io.is_async) os.SOCK.NONBLOCK else 0; | 654 | const opt_non_block = 0; |
| 655 | const sockfd = try os.socket( | 655 | const sockfd = try os.socket( |
| 656 | os.AF.UNIX, | 656 | os.AF.UNIX, |
| 657 | os.SOCK.STREAM | os.SOCK.CLOEXEC | opt_non_block, | 657 | os.SOCK.STREAM | os.SOCK.CLOEXEC | opt_non_block, |
| ... | @@ -660,17 +660,9 @@ pub fn connectUnixSocket(path: []const u8) !Stream { | ... | @@ -660,17 +660,9 @@ pub fn connectUnixSocket(path: []const u8) !Stream { |
| 660 | errdefer os.closeSocket(sockfd); | 660 | errdefer os.closeSocket(sockfd); |
| 661 | 661 | ||
| 662 | var addr = try std.net.Address.initUnix(path); | 662 | var addr = try std.net.Address.initUnix(path); |
| 663 | try os.connect(sockfd, &addr.any, addr.getOsSockLen()); | ||
| 663 | 664 | ||
| 664 | if (std.io.is_async) { | 665 | return Stream{ .handle = sockfd }; |
| 665 | const loop = std.event.Loop.instance orelse return error.WouldBlock; | ||
| 666 | try loop.connect(sockfd, &addr.any, addr.getOsSockLen()); | ||
| 667 | } else { | ||
| 668 | try os.connect(sockfd, &addr.any, addr.getOsSockLen()); | ||
| 669 | } | ||
| 670 | |||
| 671 | return Stream{ | ||
| 672 | .handle = sockfd, | ||
| 673 | }; | ||
| 674 | } | 666 | } |
| 675 | 667 | ||
| 676 | fn if_nametoindex(name: []const u8) IPv6InterfaceError!u32 { | 668 | fn if_nametoindex(name: []const u8) IPv6InterfaceError!u32 { |
| ... | @@ -742,18 +734,13 @@ pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) T | ... | @@ -742,18 +734,13 @@ pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) T |
| 742 | pub const TcpConnectToAddressError = std.os.SocketError || std.os.ConnectError; | 734 | pub const TcpConnectToAddressError = std.os.SocketError || std.os.ConnectError; |
| 743 | 735 | ||
| 744 | pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream { | 736 | pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream { |
| 745 | const nonblock = if (std.io.is_async) os.SOCK.NONBLOCK else 0; | 737 | const nonblock = 0; |
| 746 | const sock_flags = os.SOCK.STREAM | nonblock | | 738 | const sock_flags = os.SOCK.STREAM | nonblock | |
| 747 | (if (builtin.target.os.tag == .windows) 0 else os.SOCK.CLOEXEC); | 739 | (if (builtin.target.os.tag == .windows) 0 else os.SOCK.CLOEXEC); |
| 748 | const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO.TCP); | 740 | const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO.TCP); |
| 749 | errdefer os.closeSocket(sockfd); | 741 | errdefer os.closeSocket(sockfd); |
| 750 | 742 | ||
| 751 | if (std.io.is_async) { | 743 | try os.connect(sockfd, &address.any, address.getOsSockLen()); |
| 752 | const loop = std.event.Loop.instance orelse return error.WouldBlock; | ||
| 753 | try loop.connect(sockfd, &address.any, address.getOsSockLen()); | ||
| 754 | } else { | ||
| 755 | try os.connect(sockfd, &address.any, address.getOsSockLen()); | ||
| 756 | } | ||
| 757 | 744 | ||
| 758 | return Stream{ .handle = sockfd }; | 745 | return Stream{ .handle = sockfd }; |
| 759 | } | 746 | } |
| ... | @@ -1618,11 +1605,7 @@ fn resMSendRc( | ... | @@ -1618,11 +1605,7 @@ fn resMSendRc( |
| 1618 | if (answers[i].len == 0) { | 1605 | if (answers[i].len == 0) { |
| 1619 | var j: usize = 0; | 1606 | var j: usize = 0; |
| 1620 | while (j < ns.len) : (j += 1) { | 1607 | while (j < ns.len) : (j += 1) { |
| 1621 | if (std.io.is_async) { | 1608 | _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined; |
| 1622 | _ = std.event.Loop.instance.?.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined; | ||
| 1623 | } else { | ||
| 1624 | _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined; | ||
| 1625 | } | ||
| 1626 | } | 1609 | } |
| 1627 | } | 1610 | } |
| 1628 | } | 1611 | } |
| ... | @@ -1637,10 +1620,7 @@ fn resMSendRc( | ... | @@ -1637,10 +1620,7 @@ fn resMSendRc( |
| 1637 | 1620 | ||
| 1638 | while (true) { | 1621 | while (true) { |
| 1639 | var sl_copy = sl; | 1622 | var sl_copy = sl; |
| 1640 | const rlen = if (std.io.is_async) | 1623 | const rlen = os.recvfrom(fd, answer_bufs[next], 0, &sa.any, &sl_copy) catch break; |
| 1641 | std.event.Loop.instance.?.recvfrom(fd, answer_bufs[next], 0, &sa.any, &sl_copy) catch break | ||
| 1642 | else | ||
| 1643 | os.recvfrom(fd, answer_bufs[next], 0, &sa.any, &sl_copy) catch break; | ||
| 1644 | 1624 | ||
| 1645 | // Ignore non-identifiable packets | 1625 | // Ignore non-identifiable packets |
| 1646 | if (rlen < 4) continue; | 1626 | if (rlen < 4) continue; |
| ... | @@ -1666,11 +1646,7 @@ fn resMSendRc( | ... | @@ -1666,11 +1646,7 @@ fn resMSendRc( |
| 1666 | 0, 3 => {}, | 1646 | 0, 3 => {}, |
| 1667 | 2 => if (servfail_retry != 0) { | 1647 | 2 => if (servfail_retry != 0) { |
| 1668 | servfail_retry -= 1; | 1648 | servfail_retry -= 1; |
| 1669 | if (std.io.is_async) { | 1649 | _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined; |
| 1670 | _ = std.event.Loop.instance.?.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined; | ||
| 1671 | } else { | ||
| 1672 | _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined; | ||
| 1673 | } | ||
| 1674 | }, | 1650 | }, |
| 1675 | else => continue, | 1651 | else => continue, |
| 1676 | } | 1652 | } |
| ... | @@ -1778,14 +1754,10 @@ pub const Stream = struct { | ... | @@ -1778,14 +1754,10 @@ pub const Stream = struct { |
| 1778 | 1754 | ||
| 1779 | pub fn read(self: Stream, buffer: []u8) ReadError!usize { | 1755 | pub fn read(self: Stream, buffer: []u8) ReadError!usize { |
| 1780 | if (builtin.os.tag == .windows) { | 1756 | if (builtin.os.tag == .windows) { |
| 1781 | return os.windows.ReadFile(self.handle, buffer, null, io.default_mode); | 1757 | return os.windows.ReadFile(self.handle, buffer, null); |
| 1782 | } | 1758 | } |
| 1783 | 1759 | ||
| 1784 | if (std.io.is_async) { | 1760 | return os.read(self.handle, buffer); |
| 1785 | return std.event.Loop.instance.?.read(self.handle, buffer, false); | ||
| 1786 | } else { | ||
| 1787 | return os.read(self.handle, buffer); | ||
| 1788 | } | ||
| 1789 | } | 1761 | } |
| 1790 | 1762 | ||
| 1791 | pub fn readv(s: Stream, iovecs: []const os.iovec) ReadError!usize { | 1763 | pub fn readv(s: Stream, iovecs: []const os.iovec) ReadError!usize { |
| ... | @@ -1793,7 +1765,7 @@ pub const Stream = struct { | ... | @@ -1793,7 +1765,7 @@ pub const Stream = struct { |
| 1793 | // TODO improve this to use ReadFileScatter | 1765 | // TODO improve this to use ReadFileScatter |
| 1794 | if (iovecs.len == 0) return @as(usize, 0); | 1766 | if (iovecs.len == 0) return @as(usize, 0); |
| 1795 | const first = iovecs[0]; | 1767 | const first = iovecs[0]; |
| 1796 | return os.windows.ReadFile(s.handle, first.iov_base[0..first.iov_len], null, io.default_mode); | 1768 | return os.windows.ReadFile(s.handle, first.iov_base[0..first.iov_len], null); |
| 1797 | } | 1769 | } |
| 1798 | 1770 | ||
| 1799 | return os.readv(s.handle, iovecs); | 1771 | return os.readv(s.handle, iovecs); |
| ... | @@ -1827,14 +1799,10 @@ pub const Stream = struct { | ... | @@ -1827,14 +1799,10 @@ pub const Stream = struct { |
| 1827 | /// use non-blocking I/O. | 1799 | /// use non-blocking I/O. |
| 1828 | pub fn write(self: Stream, buffer: []const u8) WriteError!usize { | 1800 | pub fn write(self: Stream, buffer: []const u8) WriteError!usize { |
| 1829 | if (builtin.os.tag == .windows) { | 1801 | if (builtin.os.tag == .windows) { |
| 1830 | return os.windows.WriteFile(self.handle, buffer, null, io.default_mode); | 1802 | return os.windows.WriteFile(self.handle, buffer, null); |
| 1831 | } | 1803 | } |
| 1832 | 1804 | ||
| 1833 | if (std.io.is_async) { | 1805 | return os.write(self.handle, buffer); |
| 1834 | return std.event.Loop.instance.?.write(self.handle, buffer, false); | ||
| 1835 | } else { | ||
| 1836 | return os.write(self.handle, buffer); | ||
| 1837 | } | ||
| 1838 | } | 1806 | } |
| 1839 | 1807 | ||
| 1840 | pub fn writeAll(self: Stream, bytes: []const u8) WriteError!void { | 1808 | pub fn writeAll(self: Stream, bytes: []const u8) WriteError!void { |
| ... | @@ -1847,15 +1815,7 @@ pub const Stream = struct { | ... | @@ -1847,15 +1815,7 @@ pub const Stream = struct { |
| 1847 | /// See https://github.com/ziglang/zig/issues/7699 | 1815 | /// See https://github.com/ziglang/zig/issues/7699 |
| 1848 | /// See equivalent function: `std.fs.File.writev`. | 1816 | /// See equivalent function: `std.fs.File.writev`. |
| 1849 | pub fn writev(self: Stream, iovecs: []const os.iovec_const) WriteError!usize { | 1817 | pub fn writev(self: Stream, iovecs: []const os.iovec_const) WriteError!usize { |
| 1850 | if (std.io.is_async) { | 1818 | return os.writev(self.handle, iovecs); |
| 1851 | // TODO improve to actually take advantage of writev syscall, if available. | ||
| 1852 | if (iovecs.len == 0) return 0; | ||
| 1853 | const first_buffer = iovecs[0].iov_base[0..iovecs[0].iov_len]; | ||
| 1854 | try self.write(first_buffer); | ||
| 1855 | return first_buffer.len; | ||
| 1856 | } else { | ||
| 1857 | return os.writev(self.handle, iovecs); | ||
| 1858 | } | ||
| 1859 | } | 1819 | } |
| 1860 | 1820 | ||
| 1861 | /// The `iovecs` parameter is mutable because this function needs to mutate the fields in | 1821 | /// The `iovecs` parameter is mutable because this function needs to mutate the fields in |
| ... | @@ -1927,7 +1887,7 @@ pub const StreamServer = struct { | ... | @@ -1927,7 +1887,7 @@ pub const StreamServer = struct { |
| 1927 | } | 1887 | } |
| 1928 | 1888 | ||
| 1929 | pub fn listen(self: *StreamServer, address: Address) !void { | 1889 | pub fn listen(self: *StreamServer, address: Address) !void { |
| 1930 | const nonblock = if (std.io.is_async) os.SOCK.NONBLOCK else 0; | 1890 | const nonblock = 0; |
| 1931 | const sock_flags = os.SOCK.STREAM | os.SOCK.CLOEXEC | nonblock; | 1891 | const sock_flags = os.SOCK.STREAM | os.SOCK.CLOEXEC | nonblock; |
| 1932 | var use_sock_flags: u32 = sock_flags; | 1892 | var use_sock_flags: u32 = sock_flags; |
| 1933 | if (self.force_nonblocking) use_sock_flags |= os.SOCK.NONBLOCK; | 1893 | if (self.force_nonblocking) use_sock_flags |= os.SOCK.NONBLOCK; |
| ... | @@ -2016,14 +1976,7 @@ pub const StreamServer = struct { | ... | @@ -2016,14 +1976,7 @@ pub const StreamServer = struct { |
| 2016 | pub fn accept(self: *StreamServer) AcceptError!Connection { | 1976 | pub fn accept(self: *StreamServer) AcceptError!Connection { |
| 2017 | var accepted_addr: Address = undefined; | 1977 | var accepted_addr: Address = undefined; |
| 2018 | var adr_len: os.socklen_t = @sizeOf(Address); | 1978 | var adr_len: os.socklen_t = @sizeOf(Address); |
| 2019 | const accept_result = blk: { | 1979 | const accept_result = os.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK.CLOEXEC); |
| 2020 | if (std.io.is_async) { | ||
| 2021 | const loop = std.event.Loop.instance orelse return error.UnexpectedError; | ||
| 2022 | break :blk loop.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK.CLOEXEC); | ||
| 2023 | } else { | ||
| 2024 | break :blk os.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK.CLOEXEC); | ||
| 2025 | } | ||
| 2026 | }; | ||
| 2027 | 1980 | ||
| 2028 | if (accept_result) |fd| { | 1981 | if (accept_result) |fd| { |
| 2029 | return Connection{ | 1982 | return Connection{ |
lib/std/net/test.zig-48| ... | @@ -207,54 +207,6 @@ test "listen on a port, send bytes, receive bytes" { | ... | @@ -207,54 +207,6 @@ test "listen on a port, send bytes, receive bytes" { |
| 207 | try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]); | 207 | try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | test "listen on a port, send bytes, receive bytes, async-only" { | ||
| 211 | if (!std.io.is_async) return error.SkipZigTest; | ||
| 212 | |||
| 213 | if (builtin.os.tag != .linux and !builtin.os.tag.isDarwin()) { | ||
| 214 | // TODO build abstractions for other operating systems | ||
| 215 | return error.SkipZigTest; | ||
| 216 | } | ||
| 217 | |||
| 218 | // TODO doing this at comptime crashed the compiler | ||
| 219 | const localhost = try net.Address.parseIp("127.0.0.1", 0); | ||
| 220 | |||
| 221 | var server = net.StreamServer.init(net.StreamServer.Options{}); | ||
| 222 | defer server.deinit(); | ||
| 223 | try server.listen(localhost); | ||
| 224 | |||
| 225 | var server_frame = async testServer(&server); | ||
| 226 | var client_frame = async testClient(server.listen_address); | ||
| 227 | |||
| 228 | try await server_frame; | ||
| 229 | try await client_frame; | ||
| 230 | } | ||
| 231 | |||
| 232 | test "listen on ipv4 try connect on ipv6 then ipv4" { | ||
| 233 | if (!std.io.is_async) return error.SkipZigTest; | ||
| 234 | |||
| 235 | if (builtin.os.tag != .linux and !builtin.os.tag.isDarwin()) { | ||
| 236 | // TODO build abstractions for other operating systems | ||
| 237 | return error.SkipZigTest; | ||
| 238 | } | ||
| 239 | |||
| 240 | // TODO doing this at comptime crashed the compiler | ||
| 241 | const localhost = try net.Address.parseIp("127.0.0.1", 0); | ||
| 242 | |||
| 243 | var server = net.StreamServer.init(net.StreamServer.Options{}); | ||
| 244 | defer server.deinit(); | ||
| 245 | try server.listen(localhost); | ||
| 246 | |||
| 247 | var server_frame = async testServer(&server); | ||
| 248 | var client_frame = async testClientToHost( | ||
| 249 | testing.allocator, | ||
| 250 | "localhost", | ||
| 251 | server.listen_address.getPort(), | ||
| 252 | ); | ||
| 253 | |||
| 254 | try await server_frame; | ||
| 255 | try await client_frame; | ||
| 256 | } | ||
| 257 | |||
| 258 | test "listen on an in use port" { | 210 | test "listen on an in use port" { |
| 259 | if (builtin.os.tag != .linux and comptime !builtin.os.tag.isDarwin()) { | 211 | if (builtin.os.tag != .linux and comptime !builtin.os.tag.isDarwin()) { |
| 260 | // TODO build abstractions for other operating systems | 212 | // TODO build abstractions for other operating systems |
lib/std/os.zig+6-29| ... | @@ -683,11 +683,7 @@ fn getRandomBytesDevURandom(buf: []u8) !void { | ... | @@ -683,11 +683,7 @@ fn getRandomBytesDevURandom(buf: []u8) !void { |
| 683 | return error.NoDevice; | 683 | return error.NoDevice; |
| 684 | } | 684 | } |
| 685 | 685 | ||
| 686 | const file = std.fs.File{ | 686 | const file = std.fs.File{ .handle = fd }; |
| 687 | .handle = fd, | ||
| 688 | .capable_io_mode = .blocking, | ||
| 689 | .intended_io_mode = .blocking, | ||
| 690 | }; | ||
| 691 | const stream = file.reader(); | 687 | const stream = file.reader(); |
| 692 | stream.readNoEof(buf) catch return error.Unexpected; | 688 | stream.readNoEof(buf) catch return error.Unexpected; |
| 693 | } | 689 | } |
| ... | @@ -856,7 +852,7 @@ pub const ReadError = error{ | ... | @@ -856,7 +852,7 @@ pub const ReadError = error{ |
| 856 | pub fn read(fd: fd_t, buf: []u8) ReadError!usize { | 852 | pub fn read(fd: fd_t, buf: []u8) ReadError!usize { |
| 857 | if (buf.len == 0) return 0; | 853 | if (buf.len == 0) return 0; |
| 858 | if (builtin.os.tag == .windows) { | 854 | if (builtin.os.tag == .windows) { |
| 859 | return windows.ReadFile(fd, buf, null, std.io.default_mode); | 855 | return windows.ReadFile(fd, buf, null); |
| 860 | } | 856 | } |
| 861 | if (builtin.os.tag == .wasi and !builtin.link_libc) { | 857 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 862 | const iovs = [1]iovec{iovec{ | 858 | const iovs = [1]iovec{iovec{ |
| ... | @@ -995,7 +991,7 @@ pub const PReadError = ReadError || error{Unseekable}; | ... | @@ -995,7 +991,7 @@ pub const PReadError = ReadError || error{Unseekable}; |
| 995 | pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { | 991 | pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { |
| 996 | if (buf.len == 0) return 0; | 992 | if (buf.len == 0) return 0; |
| 997 | if (builtin.os.tag == .windows) { | 993 | if (builtin.os.tag == .windows) { |
| 998 | return windows.ReadFile(fd, buf, offset, std.io.default_mode); | 994 | return windows.ReadFile(fd, buf, offset); |
| 999 | } | 995 | } |
| 1000 | if (builtin.os.tag == .wasi and !builtin.link_libc) { | 996 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 1001 | const iovs = [1]iovec{iovec{ | 997 | const iovs = [1]iovec{iovec{ |
| ... | @@ -1257,7 +1253,7 @@ pub const WriteError = error{ | ... | @@ -1257,7 +1253,7 @@ pub const WriteError = error{ |
| 1257 | pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { | 1253 | pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { |
| 1258 | if (bytes.len == 0) return 0; | 1254 | if (bytes.len == 0) return 0; |
| 1259 | if (builtin.os.tag == .windows) { | 1255 | if (builtin.os.tag == .windows) { |
| 1260 | return windows.WriteFile(fd, bytes, null, std.io.default_mode); | 1256 | return windows.WriteFile(fd, bytes, null); |
| 1261 | } | 1257 | } |
| 1262 | 1258 | ||
| 1263 | if (builtin.os.tag == .wasi and !builtin.link_libc) { | 1259 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| ... | @@ -1415,7 +1411,7 @@ pub const PWriteError = WriteError || error{Unseekable}; | ... | @@ -1415,7 +1411,7 @@ pub const PWriteError = WriteError || error{Unseekable}; |
| 1415 | pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { | 1411 | pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { |
| 1416 | if (bytes.len == 0) return 0; | 1412 | if (bytes.len == 0) return 0; |
| 1417 | if (builtin.os.tag == .windows) { | 1413 | if (builtin.os.tag == .windows) { |
| 1418 | return windows.WriteFile(fd, bytes, offset, std.io.default_mode); | 1414 | return windows.WriteFile(fd, bytes, offset); |
| 1419 | } | 1415 | } |
| 1420 | if (builtin.os.tag == .wasi and !builtin.link_libc) { | 1416 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 1421 | const ciovs = [1]iovec_const{iovec_const{ | 1417 | const ciovs = [1]iovec_const{iovec_const{ |
| ... | @@ -1711,7 +1707,6 @@ fn openOptionsFromFlagsWindows(flags: u32) windows.OpenFileOptions { | ... | @@ -1711,7 +1707,6 @@ fn openOptionsFromFlagsWindows(flags: u32) windows.OpenFileOptions { |
| 1711 | 1707 | ||
| 1712 | return .{ | 1708 | return .{ |
| 1713 | .access_mask = access_mask, | 1709 | .access_mask = access_mask, |
| 1714 | .io_mode = .blocking, | ||
| 1715 | .creation = creation, | 1710 | .creation = creation, |
| 1716 | .filter = filter, | 1711 | .filter = filter, |
| 1717 | .follow_symlinks = follow_symlinks, | 1712 | .follow_symlinks = follow_symlinks, |
| ... | @@ -2797,7 +2792,6 @@ pub fn renameatW( | ... | @@ -2797,7 +2792,6 @@ pub fn renameatW( |
| 2797 | .dir = old_dir_fd, | 2792 | .dir = old_dir_fd, |
| 2798 | .access_mask = windows.SYNCHRONIZE | windows.GENERIC_WRITE | windows.DELETE, | 2793 | .access_mask = windows.SYNCHRONIZE | windows.GENERIC_WRITE | windows.DELETE, |
| 2799 | .creation = windows.FILE_OPEN, | 2794 | .creation = windows.FILE_OPEN, |
| 2800 | .io_mode = .blocking, | ||
| 2801 | .filter = .any, // This function is supposed to rename both files and directories. | 2795 | .filter = .any, // This function is supposed to rename both files and directories. |
| 2802 | .follow_symlinks = false, | 2796 | .follow_symlinks = false, |
| 2803 | }) catch |err| switch (err) { | 2797 | }) catch |err| switch (err) { |
| ... | @@ -2962,7 +2956,6 @@ pub fn mkdiratW(dir_fd: fd_t, sub_path_w: []const u16, mode: u32) MakeDirError!v | ... | @@ -2962,7 +2956,6 @@ pub fn mkdiratW(dir_fd: fd_t, sub_path_w: []const u16, mode: u32) MakeDirError!v |
| 2962 | .dir = dir_fd, | 2956 | .dir = dir_fd, |
| 2963 | .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE, | 2957 | .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE, |
| 2964 | .creation = windows.FILE_CREATE, | 2958 | .creation = windows.FILE_CREATE, |
| 2965 | .io_mode = .blocking, | ||
| 2966 | .filter = .dir_only, | 2959 | .filter = .dir_only, |
| 2967 | }) catch |err| switch (err) { | 2960 | }) catch |err| switch (err) { |
| 2968 | error.IsDir => unreachable, | 2961 | error.IsDir => unreachable, |
| ... | @@ -3042,7 +3035,6 @@ pub fn mkdirW(dir_path_w: []const u16, mode: u32) MakeDirError!void { | ... | @@ -3042,7 +3035,6 @@ pub fn mkdirW(dir_path_w: []const u16, mode: u32) MakeDirError!void { |
| 3042 | .dir = std.fs.cwd().fd, | 3035 | .dir = std.fs.cwd().fd, |
| 3043 | .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE, | 3036 | .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE, |
| 3044 | .creation = windows.FILE_CREATE, | 3037 | .creation = windows.FILE_CREATE, |
| 3045 | .io_mode = .blocking, | ||
| 3046 | .filter = .dir_only, | 3038 | .filter = .dir_only, |
| 3047 | }) catch |err| switch (err) { | 3039 | }) catch |err| switch (err) { |
| 3048 | error.IsDir => unreachable, | 3040 | error.IsDir => unreachable, |
| ... | @@ -5440,7 +5432,6 @@ pub fn realpathW(pathname: []const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPat | ... | @@ -5440,7 +5432,6 @@ pub fn realpathW(pathname: []const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPat |
| 5440 | .access_mask = access_mask, | 5432 | .access_mask = access_mask, |
| 5441 | .share_access = share_access, | 5433 | .share_access = share_access, |
| 5442 | .creation = creation, | 5434 | .creation = creation, |
| 5443 | .io_mode = .blocking, | ||
| 5444 | .filter = .any, | 5435 | .filter = .any, |
| 5445 | }) catch |err| switch (err) { | 5436 | }) catch |err| switch (err) { |
| 5446 | error.WouldBlock => unreachable, | 5437 | error.WouldBlock => unreachable, |
| ... | @@ -6404,12 +6395,7 @@ pub fn sendfile( | ... | @@ -6404,12 +6395,7 @@ pub fn sendfile( |
| 6404 | // manually, the same as ENOSYS. | 6395 | // manually, the same as ENOSYS. |
| 6405 | break :sf; | 6396 | break :sf; |
| 6406 | }, | 6397 | }, |
| 6407 | .AGAIN => if (std.event.Loop.instance) |loop| { | 6398 | .AGAIN => return error.WouldBlock, |
| 6408 | loop.waitUntilFdWritable(out_fd); | ||
| 6409 | continue; | ||
| 6410 | } else { | ||
| 6411 | return error.WouldBlock; | ||
| 6412 | }, | ||
| 6413 | .IO => return error.InputOutput, | 6399 | .IO => return error.InputOutput, |
| 6414 | .PIPE => return error.BrokenPipe, | 6400 | .PIPE => return error.BrokenPipe, |
| 6415 | .NOMEM => return error.SystemResources, | 6401 | .NOMEM => return error.SystemResources, |
| ... | @@ -6476,18 +6462,12 @@ pub fn sendfile( | ... | @@ -6476,18 +6462,12 @@ pub fn sendfile( |
| 6476 | 6462 | ||
| 6477 | .AGAIN => if (amt != 0) { | 6463 | .AGAIN => if (amt != 0) { |
| 6478 | return amt; | 6464 | return amt; |
| 6479 | } else if (std.event.Loop.instance) |loop| { | ||
| 6480 | loop.waitUntilFdWritable(out_fd); | ||
| 6481 | continue; | ||
| 6482 | } else { | 6465 | } else { |
| 6483 | return error.WouldBlock; | 6466 | return error.WouldBlock; |
| 6484 | }, | 6467 | }, |
| 6485 | 6468 | ||
| 6486 | .BUSY => if (amt != 0) { | 6469 | .BUSY => if (amt != 0) { |
| 6487 | return amt; | 6470 | return amt; |
| 6488 | } else if (std.event.Loop.instance) |loop| { | ||
| 6489 | loop.waitUntilFdReadable(in_fd); | ||
| 6490 | continue; | ||
| 6491 | } else { | 6471 | } else { |
| 6492 | return error.WouldBlock; | 6472 | return error.WouldBlock; |
| 6493 | }, | 6473 | }, |
| ... | @@ -6550,9 +6530,6 @@ pub fn sendfile( | ... | @@ -6550,9 +6530,6 @@ pub fn sendfile( |
| 6550 | 6530 | ||
| 6551 | .AGAIN => if (amt != 0) { | 6531 | .AGAIN => if (amt != 0) { |
| 6552 | return amt; | 6532 | return amt; |
| 6553 | } else if (std.event.Loop.instance) |loop| { | ||
| 6554 | loop.waitUntilFdWritable(out_fd); | ||
| 6555 | continue; | ||
| 6556 | } else { | 6533 | } else { |
| 6557 | return error.WouldBlock; | 6534 | return error.WouldBlock; |
| 6558 | }, | 6535 | }, |
lib/std/os/windows.zig+50-150| ... | @@ -49,7 +49,6 @@ pub const OpenFileOptions = struct { | ... | @@ -49,7 +49,6 @@ pub const OpenFileOptions = struct { |
| 49 | sa: ?*SECURITY_ATTRIBUTES = null, | 49 | sa: ?*SECURITY_ATTRIBUTES = null, |
| 50 | share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, | 50 | share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, |
| 51 | creation: ULONG, | 51 | creation: ULONG, |
| 52 | io_mode: std.io.ModeOverride, | ||
| 53 | /// If true, tries to open path as a directory. | 52 | /// If true, tries to open path as a directory. |
| 54 | /// Defaults to false. | 53 | /// Defaults to false. |
| 55 | filter: Filter = .file_only, | 54 | filter: Filter = .file_only, |
| ... | @@ -95,7 +94,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN | ... | @@ -95,7 +94,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 95 | .SecurityQualityOfService = null, | 94 | .SecurityQualityOfService = null, |
| 96 | }; | 95 | }; |
| 97 | var io: IO_STATUS_BLOCK = undefined; | 96 | var io: IO_STATUS_BLOCK = undefined; |
| 98 | const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; | 97 | const blocking_flag: ULONG = FILE_SYNCHRONOUS_IO_NONALERT; |
| 99 | const file_or_dir_flag: ULONG = switch (options.filter) { | 98 | const file_or_dir_flag: ULONG = switch (options.filter) { |
| 100 | .file_only => FILE_NON_DIRECTORY_FILE, | 99 | .file_only => FILE_NON_DIRECTORY_FILE, |
| 101 | .dir_only => FILE_DIRECTORY_FILE, | 100 | .dir_only => FILE_DIRECTORY_FILE, |
| ... | @@ -119,12 +118,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN | ... | @@ -119,12 +118,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 119 | 0, | 118 | 0, |
| 120 | ); | 119 | ); |
| 121 | switch (rc) { | 120 | switch (rc) { |
| 122 | .SUCCESS => { | 121 | .SUCCESS => return result, |
| 123 | if (std.io.is_async and options.io_mode == .evented) { | ||
| 124 | _ = CreateIoCompletionPort(result, std.event.Loop.instance.?.os_data.io_port, undefined, undefined) catch undefined; | ||
| 125 | } | ||
| 126 | return result; | ||
| 127 | }, | ||
| 128 | .OBJECT_NAME_INVALID => unreachable, | 122 | .OBJECT_NAME_INVALID => unreachable, |
| 129 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, | 123 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 130 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, | 124 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| ... | @@ -457,81 +451,36 @@ pub const ReadFileError = error{ | ... | @@ -457,81 +451,36 @@ pub const ReadFileError = error{ |
| 457 | 451 | ||
| 458 | /// If buffer's length exceeds what a Windows DWORD integer can hold, it will be broken into | 452 | /// If buffer's length exceeds what a Windows DWORD integer can hold, it will be broken into |
| 459 | /// multiple non-atomic reads. | 453 | /// multiple non-atomic reads. |
| 460 | pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64, io_mode: std.io.ModeOverride) ReadFileError!usize { | 454 | pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usize { |
| 461 | if (io_mode != .blocking) { | 455 | while (true) { |
| 462 | const loop = std.event.Loop.instance.?; | 456 | const want_read_count: DWORD = @min(@as(DWORD, maxInt(DWORD)), buffer.len); |
| 463 | // TODO make getting the file position non-blocking | 457 | var amt_read: DWORD = undefined; |
| 464 | const off = if (offset) |o| o else try SetFilePointerEx_CURRENT_get(in_hFile); | 458 | var overlapped_data: OVERLAPPED = undefined; |
| 465 | var resume_node = std.event.Loop.ResumeNode.Basic{ | 459 | const overlapped: ?*OVERLAPPED = if (offset) |off| blk: { |
| 466 | .base = .{ | 460 | overlapped_data = .{ |
| 467 | .id = .Basic, | 461 | .Internal = 0, |
| 468 | .handle = @frame(), | 462 | .InternalHigh = 0, |
| 469 | .overlapped = OVERLAPPED{ | 463 | .DUMMYUNIONNAME = .{ |
| 470 | .Internal = 0, | 464 | .DUMMYSTRUCTNAME = .{ |
| 471 | .InternalHigh = 0, | 465 | .Offset = @as(u32, @truncate(off)), |
| 472 | .DUMMYUNIONNAME = .{ | 466 | .OffsetHigh = @as(u32, @truncate(off >> 32)), |
| 473 | .DUMMYSTRUCTNAME = .{ | ||
| 474 | .Offset = @as(u32, @truncate(off)), | ||
| 475 | .OffsetHigh = @as(u32, @truncate(off >> 32)), | ||
| 476 | }, | ||
| 477 | }, | 467 | }, |
| 478 | .hEvent = null, | ||
| 479 | }, | 468 | }, |
| 480 | }, | 469 | .hEvent = null, |
| 481 | }; | 470 | }; |
| 482 | loop.beginOneEvent(); | 471 | break :blk &overlapped_data; |
| 483 | suspend { | 472 | } else null; |
| 484 | // TODO handle buffer bigger than DWORD can hold | 473 | if (kernel32.ReadFile(in_hFile, buffer.ptr, want_read_count, &amt_read, overlapped) == 0) { |
| 485 | _ = kernel32.ReadFile(in_hFile, buffer.ptr, @as(DWORD, @intCast(buffer.len)), null, &resume_node.base.overlapped); | ||
| 486 | } | ||
| 487 | var bytes_transferred: DWORD = undefined; | ||
| 488 | if (kernel32.GetOverlappedResult(in_hFile, &resume_node.base.overlapped, &bytes_transferred, FALSE) == 0) { | ||
| 489 | switch (kernel32.GetLastError()) { | 474 | switch (kernel32.GetLastError()) { |
| 490 | .IO_PENDING => unreachable, | 475 | .IO_PENDING => unreachable, |
| 491 | .OPERATION_ABORTED => return error.OperationAborted, | 476 | .OPERATION_ABORTED => continue, |
| 492 | .BROKEN_PIPE => return error.BrokenPipe, | 477 | .BROKEN_PIPE => return 0, |
| 478 | .HANDLE_EOF => return 0, | ||
| 493 | .NETNAME_DELETED => return error.NetNameDeleted, | 479 | .NETNAME_DELETED => return error.NetNameDeleted, |
| 494 | .HANDLE_EOF => return @as(usize, bytes_transferred), | ||
| 495 | else => |err| return unexpectedError(err), | 480 | else => |err| return unexpectedError(err), |
| 496 | } | 481 | } |
| 497 | } | 482 | } |
| 498 | if (offset == null) { | 483 | return amt_read; |
| 499 | // TODO make setting the file position non-blocking | ||
| 500 | const new_off = off + bytes_transferred; | ||
| 501 | try SetFilePointerEx_CURRENT(in_hFile, @as(i64, @bitCast(new_off))); | ||
| 502 | } | ||
| 503 | return @as(usize, bytes_transferred); | ||
| 504 | } else { | ||
| 505 | while (true) { | ||
| 506 | const want_read_count: DWORD = @min(@as(DWORD, maxInt(DWORD)), buffer.len); | ||
| 507 | var amt_read: DWORD = undefined; | ||
| 508 | var overlapped_data: OVERLAPPED = undefined; | ||
| 509 | const overlapped: ?*OVERLAPPED = if (offset) |off| blk: { | ||
| 510 | overlapped_data = .{ | ||
| 511 | .Internal = 0, | ||
| 512 | .InternalHigh = 0, | ||
| 513 | .DUMMYUNIONNAME = .{ | ||
| 514 | .DUMMYSTRUCTNAME = .{ | ||
| 515 | .Offset = @as(u32, @truncate(off)), | ||
| 516 | .OffsetHigh = @as(u32, @truncate(off >> 32)), | ||
| 517 | }, | ||
| 518 | }, | ||
| 519 | .hEvent = null, | ||
| 520 | }; | ||
| 521 | break :blk &overlapped_data; | ||
| 522 | } else null; | ||
| 523 | if (kernel32.ReadFile(in_hFile, buffer.ptr, want_read_count, &amt_read, overlapped) == 0) { | ||
| 524 | switch (kernel32.GetLastError()) { | ||
| 525 | .IO_PENDING => unreachable, | ||
| 526 | .OPERATION_ABORTED => continue, | ||
| 527 | .BROKEN_PIPE => return 0, | ||
| 528 | .HANDLE_EOF => return 0, | ||
| 529 | .NETNAME_DELETED => return error.NetNameDeleted, | ||
| 530 | else => |err| return unexpectedError(err), | ||
| 531 | } | ||
| 532 | } | ||
| 533 | return amt_read; | ||
| 534 | } | ||
| 535 | } | 484 | } |
| 536 | } | 485 | } |
| 537 | 486 | ||
| ... | @@ -550,85 +499,38 @@ pub fn WriteFile( | ... | @@ -550,85 +499,38 @@ pub fn WriteFile( |
| 550 | handle: HANDLE, | 499 | handle: HANDLE, |
| 551 | bytes: []const u8, | 500 | bytes: []const u8, |
| 552 | offset: ?u64, | 501 | offset: ?u64, |
| 553 | io_mode: std.io.ModeOverride, | ||
| 554 | ) WriteFileError!usize { | 502 | ) WriteFileError!usize { |
| 555 | if (std.event.Loop.instance != null and io_mode != .blocking) { | 503 | var bytes_written: DWORD = undefined; |
| 556 | const loop = std.event.Loop.instance.?; | 504 | var overlapped_data: OVERLAPPED = undefined; |
| 557 | // TODO make getting the file position non-blocking | 505 | const overlapped: ?*OVERLAPPED = if (offset) |off| blk: { |
| 558 | const off = if (offset) |o| o else try SetFilePointerEx_CURRENT_get(handle); | 506 | overlapped_data = .{ |
| 559 | var resume_node = std.event.Loop.ResumeNode.Basic{ | 507 | .Internal = 0, |
| 560 | .base = .{ | 508 | .InternalHigh = 0, |
| 561 | .id = .Basic, | 509 | .DUMMYUNIONNAME = .{ |
| 562 | .handle = @frame(), | 510 | .DUMMYSTRUCTNAME = .{ |
| 563 | .overlapped = OVERLAPPED{ | 511 | .Offset = @as(u32, @truncate(off)), |
| 564 | .Internal = 0, | 512 | .OffsetHigh = @as(u32, @truncate(off >> 32)), |
| 565 | .InternalHigh = 0, | ||
| 566 | .DUMMYUNIONNAME = .{ | ||
| 567 | .DUMMYSTRUCTNAME = .{ | ||
| 568 | .Offset = @as(u32, @truncate(off)), | ||
| 569 | .OffsetHigh = @as(u32, @truncate(off >> 32)), | ||
| 570 | }, | ||
| 571 | }, | ||
| 572 | .hEvent = null, | ||
| 573 | }, | 513 | }, |
| 574 | }, | 514 | }, |
| 515 | .hEvent = null, | ||
| 575 | }; | 516 | }; |
| 576 | loop.beginOneEvent(); | 517 | break :blk &overlapped_data; |
| 577 | suspend { | 518 | } else null; |
| 578 | const adjusted_len = math.cast(DWORD, bytes.len) orelse maxInt(DWORD); | 519 | const adjusted_len = math.cast(u32, bytes.len) orelse maxInt(u32); |
| 579 | _ = kernel32.WriteFile(handle, bytes.ptr, adjusted_len, null, &resume_node.base.overlapped); | 520 | if (kernel32.WriteFile(handle, bytes.ptr, adjusted_len, &bytes_written, overlapped) == 0) { |
| 580 | } | 521 | switch (kernel32.GetLastError()) { |
| 581 | var bytes_transferred: DWORD = undefined; | 522 | .INVALID_USER_BUFFER => return error.SystemResources, |
| 582 | if (kernel32.GetOverlappedResult(handle, &resume_node.base.overlapped, &bytes_transferred, FALSE) == 0) { | 523 | .NOT_ENOUGH_MEMORY => return error.SystemResources, |
| 583 | switch (kernel32.GetLastError()) { | 524 | .OPERATION_ABORTED => return error.OperationAborted, |
| 584 | .IO_PENDING => unreachable, | 525 | .NOT_ENOUGH_QUOTA => return error.SystemResources, |
| 585 | .INVALID_USER_BUFFER => return error.SystemResources, | 526 | .IO_PENDING => unreachable, |
| 586 | .NOT_ENOUGH_MEMORY => return error.SystemResources, | 527 | .BROKEN_PIPE => return error.BrokenPipe, |
| 587 | .OPERATION_ABORTED => return error.OperationAborted, | 528 | .INVALID_HANDLE => return error.NotOpenForWriting, |
| 588 | .NOT_ENOUGH_QUOTA => return error.SystemResources, | 529 | .LOCK_VIOLATION => return error.LockViolation, |
| 589 | .BROKEN_PIPE => return error.BrokenPipe, | 530 | else => |err| return unexpectedError(err), |
| 590 | else => |err| return unexpectedError(err), | ||
| 591 | } | ||
| 592 | } | ||
| 593 | if (offset == null) { | ||
| 594 | // TODO make setting the file position non-blocking | ||
| 595 | const new_off = off + bytes_transferred; | ||
| 596 | try SetFilePointerEx_CURRENT(handle, @as(i64, @bitCast(new_off))); | ||
| 597 | } | ||
| 598 | return bytes_transferred; | ||
| 599 | } else { | ||
| 600 | var bytes_written: DWORD = undefined; | ||
| 601 | var overlapped_data: OVERLAPPED = undefined; | ||
| 602 | const overlapped: ?*OVERLAPPED = if (offset) |off| blk: { | ||
| 603 | overlapped_data = .{ | ||
| 604 | .Internal = 0, | ||
| 605 | .InternalHigh = 0, | ||
| 606 | .DUMMYUNIONNAME = .{ | ||
| 607 | .DUMMYSTRUCTNAME = .{ | ||
| 608 | .Offset = @as(u32, @truncate(off)), | ||
| 609 | .OffsetHigh = @as(u32, @truncate(off >> 32)), | ||
| 610 | }, | ||
| 611 | }, | ||
| 612 | .hEvent = null, | ||
| 613 | }; | ||
| 614 | break :blk &overlapped_data; | ||
| 615 | } else null; | ||
| 616 | const adjusted_len = math.cast(u32, bytes.len) orelse maxInt(u32); | ||
| 617 | if (kernel32.WriteFile(handle, bytes.ptr, adjusted_len, &bytes_written, overlapped) == 0) { | ||
| 618 | switch (kernel32.GetLastError()) { | ||
| 619 | .INVALID_USER_BUFFER => return error.SystemResources, | ||
| 620 | .NOT_ENOUGH_MEMORY => return error.SystemResources, | ||
| 621 | .OPERATION_ABORTED => return error.OperationAborted, | ||
| 622 | .NOT_ENOUGH_QUOTA => return error.SystemResources, | ||
| 623 | .IO_PENDING => unreachable, | ||
| 624 | .BROKEN_PIPE => return error.BrokenPipe, | ||
| 625 | .INVALID_HANDLE => return error.NotOpenForWriting, | ||
| 626 | .LOCK_VIOLATION => return error.LockViolation, | ||
| 627 | else => |err| return unexpectedError(err), | ||
| 628 | } | ||
| 629 | } | 531 | } |
| 630 | return bytes_written; | ||
| 631 | } | 532 | } |
| 533 | return bytes_written; | ||
| 632 | } | 534 | } |
| 633 | 535 | ||
| 634 | pub const SetCurrentDirectoryError = error{ | 536 | pub const SetCurrentDirectoryError = error{ |
| ... | @@ -732,7 +634,6 @@ pub fn CreateSymbolicLink( | ... | @@ -732,7 +634,6 @@ pub fn CreateSymbolicLink( |
| 732 | .access_mask = SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, | 634 | .access_mask = SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, |
| 733 | .dir = dir, | 635 | .dir = dir, |
| 734 | .creation = FILE_CREATE, | 636 | .creation = FILE_CREATE, |
| 735 | .io_mode = .blocking, | ||
| 736 | .filter = if (is_directory) .dir_only else .file_only, | 637 | .filter = if (is_directory) .dir_only else .file_only, |
| 737 | }) catch |err| switch (err) { | 638 | }) catch |err| switch (err) { |
| 738 | error.IsDir => return error.PathAlreadyExists, | 639 | error.IsDir => return error.PathAlreadyExists, |
| ... | @@ -1256,7 +1157,6 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -1256,7 +1157,6 @@ pub fn GetFinalPathNameByHandle( |
| 1256 | .access_mask = SYNCHRONIZE, | 1157 | .access_mask = SYNCHRONIZE, |
| 1257 | .share_access = FILE_SHARE_READ | FILE_SHARE_WRITE, | 1158 | .share_access = FILE_SHARE_READ | FILE_SHARE_WRITE, |
| 1258 | .creation = FILE_OPEN, | 1159 | .creation = FILE_OPEN, |
| 1259 | .io_mode = .blocking, | ||
| 1260 | }) catch |err| switch (err) { | 1160 | }) catch |err| switch (err) { |
| 1261 | error.IsDir => unreachable, | 1161 | error.IsDir => unreachable, |
| 1262 | error.NotDir => unreachable, | 1162 | error.NotDir => unreachable, |
lib/std/pdb.zig+1-1| ... | @@ -513,7 +513,7 @@ pub const Pdb = struct { | ... | @@ -513,7 +513,7 @@ pub const Pdb = struct { |
| 513 | }; | 513 | }; |
| 514 | 514 | ||
| 515 | pub fn init(allocator: mem.Allocator, path: []const u8) !Pdb { | 515 | pub fn init(allocator: mem.Allocator, path: []const u8) !Pdb { |
| 516 | const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking }); | 516 | const file = try fs.cwd().openFile(path, .{}); |
| 517 | errdefer file.close(); | 517 | errdefer file.close(); |
| 518 | 518 | ||
| 519 | return Pdb{ | 519 | return Pdb{ |
lib/std/time.zig-5| ... | @@ -9,11 +9,6 @@ pub const epoch = @import("time/epoch.zig"); | ... | @@ -9,11 +9,6 @@ pub const epoch = @import("time/epoch.zig"); |
| 9 | 9 | ||
| 10 | /// Spurious wakeups are possible and no precision of timing is guaranteed. | 10 | /// Spurious wakeups are possible and no precision of timing is guaranteed. |
| 11 | pub fn sleep(nanoseconds: u64) void { | 11 | pub fn sleep(nanoseconds: u64) void { |
| 12 | // TODO: opting out of async sleeping? | ||
| 13 | if (std.io.is_async) { | ||
| 14 | return std.event.Loop.instance.?.sleep(nanoseconds); | ||
| 15 | } | ||
| 16 | |||
| 17 | if (builtin.os.tag == .windows) { | 12 | if (builtin.os.tag == .windows) { |
| 18 | const big_ms_from_ns = nanoseconds / ns_per_ms; | 13 | const big_ms_from_ns = nanoseconds / ns_per_ms; |
| 19 | const ms = math.cast(os.windows.DWORD, big_ms_from_ns) orelse math.maxInt(os.windows.DWORD); | 14 | const ms = math.cast(os.windows.DWORD, big_ms_from_ns) orelse math.maxInt(os.windows.DWORD); |
lib/std/zig/Server.zig+2-7| ... | @@ -38,8 +38,6 @@ pub const Message = struct { | ... | @@ -38,8 +38,6 @@ pub const Message = struct { |
| 38 | /// Trailing: | 38 | /// Trailing: |
| 39 | /// * name: [tests_len]u32 | 39 | /// * name: [tests_len]u32 |
| 40 | /// - null-terminated string_bytes index | 40 | /// - null-terminated string_bytes index |
| 41 | /// * async_frame_len: [tests_len]u32, | ||
| 42 | /// - 0 means not async | ||
| 43 | /// * expected_panic_msg: [tests_len]u32, | 41 | /// * expected_panic_msg: [tests_len]u32, |
| 44 | /// - null-terminated string_bytes index | 42 | /// - null-terminated string_bytes index |
| 45 | /// - 0 means does not expect pani | 43 | /// - 0 means does not expect pani |
| ... | @@ -210,7 +208,6 @@ pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void { | ... | @@ -210,7 +208,6 @@ pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void { |
| 210 | 208 | ||
| 211 | pub const TestMetadata = struct { | 209 | pub const TestMetadata = struct { |
| 212 | names: []u32, | 210 | names: []u32, |
| 213 | async_frame_sizes: []u32, | ||
| 214 | expected_panic_msgs: []u32, | 211 | expected_panic_msgs: []u32, |
| 215 | string_bytes: []const u8, | 212 | string_bytes: []const u8, |
| 216 | }; | 213 | }; |
| ... | @@ -220,17 +217,16 @@ pub fn serveTestMetadata(s: *Server, test_metadata: TestMetadata) !void { | ... | @@ -220,17 +217,16 @@ pub fn serveTestMetadata(s: *Server, test_metadata: TestMetadata) !void { |
| 220 | .tests_len = bswap(@as(u32, @intCast(test_metadata.names.len))), | 217 | .tests_len = bswap(@as(u32, @intCast(test_metadata.names.len))), |
| 221 | .string_bytes_len = bswap(@as(u32, @intCast(test_metadata.string_bytes.len))), | 218 | .string_bytes_len = bswap(@as(u32, @intCast(test_metadata.string_bytes.len))), |
| 222 | }; | 219 | }; |
| 220 | const trailing = 2; | ||
| 223 | const bytes_len = @sizeOf(OutMessage.TestMetadata) + | 221 | const bytes_len = @sizeOf(OutMessage.TestMetadata) + |
| 224 | 3 * 4 * test_metadata.names.len + test_metadata.string_bytes.len; | 222 | trailing * @sizeOf(u32) * test_metadata.names.len + test_metadata.string_bytes.len; |
| 225 | 223 | ||
| 226 | if (need_bswap) { | 224 | if (need_bswap) { |
| 227 | bswap_u32_array(test_metadata.names); | 225 | bswap_u32_array(test_metadata.names); |
| 228 | bswap_u32_array(test_metadata.async_frame_sizes); | ||
| 229 | bswap_u32_array(test_metadata.expected_panic_msgs); | 226 | bswap_u32_array(test_metadata.expected_panic_msgs); |
| 230 | } | 227 | } |
| 231 | defer if (need_bswap) { | 228 | defer if (need_bswap) { |
| 232 | bswap_u32_array(test_metadata.names); | 229 | bswap_u32_array(test_metadata.names); |
| 233 | bswap_u32_array(test_metadata.async_frame_sizes); | ||
| 234 | bswap_u32_array(test_metadata.expected_panic_msgs); | 230 | bswap_u32_array(test_metadata.expected_panic_msgs); |
| 235 | }; | 231 | }; |
| 236 | 232 | ||
| ... | @@ -241,7 +237,6 @@ pub fn serveTestMetadata(s: *Server, test_metadata: TestMetadata) !void { | ... | @@ -241,7 +237,6 @@ pub fn serveTestMetadata(s: *Server, test_metadata: TestMetadata) !void { |
| 241 | std.mem.asBytes(&header), | 237 | std.mem.asBytes(&header), |
| 242 | // TODO: implement @ptrCast between slices changing the length | 238 | // TODO: implement @ptrCast between slices changing the length |
| 243 | std.mem.sliceAsBytes(test_metadata.names), | 239 | std.mem.sliceAsBytes(test_metadata.names), |
| 244 | std.mem.sliceAsBytes(test_metadata.async_frame_sizes), | ||
| 245 | std.mem.sliceAsBytes(test_metadata.expected_panic_msgs), | 240 | std.mem.sliceAsBytes(test_metadata.expected_panic_msgs), |
| 246 | test_metadata.string_bytes, | 241 | test_metadata.string_bytes, |
| 247 | }); | 242 | }); |
lib/std/zig/system/linux.zig+1-1| ... | @@ -328,7 +328,7 @@ fn CpuinfoParser(comptime impl: anytype) type { | ... | @@ -328,7 +328,7 @@ fn CpuinfoParser(comptime impl: anytype) type { |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { | 330 | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 331 | var f = fs.openFileAbsolute("/proc/cpuinfo", .{ .intended_io_mode = .blocking }) catch |err| switch (err) { | 331 | var f = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { |
| 332 | else => return null, | 332 | else => return null, |
| 333 | }; | 333 | }; |
| 334 | defer f.close(); | 334 | defer f.close(); |
lib/test_runner.zig+2-26| ... | @@ -4,7 +4,6 @@ const io = std.io; | ... | @@ -4,7 +4,6 @@ const io = std.io; |
| 4 | const builtin = @import("builtin"); | 4 | const builtin = @import("builtin"); |
| 5 | 5 | ||
| 6 | pub const std_options = .{ | 6 | pub const std_options = .{ |
| 7 | .io_mode = builtin.test_io_mode, | ||
| 8 | .logFn = log, | 7 | .logFn = log, |
| 9 | }; | 8 | }; |
| 10 | 9 | ||
| ... | @@ -65,24 +64,19 @@ fn mainServer() !void { | ... | @@ -65,24 +64,19 @@ fn mainServer() !void { |
| 65 | const test_fns = builtin.test_functions; | 64 | const test_fns = builtin.test_functions; |
| 66 | const names = try std.testing.allocator.alloc(u32, test_fns.len); | 65 | const names = try std.testing.allocator.alloc(u32, test_fns.len); |
| 67 | defer std.testing.allocator.free(names); | 66 | defer std.testing.allocator.free(names); |
| 68 | const async_frame_sizes = try std.testing.allocator.alloc(u32, test_fns.len); | ||
| 69 | defer std.testing.allocator.free(async_frame_sizes); | ||
| 70 | const expected_panic_msgs = try std.testing.allocator.alloc(u32, test_fns.len); | 67 | const expected_panic_msgs = try std.testing.allocator.alloc(u32, test_fns.len); |
| 71 | defer std.testing.allocator.free(expected_panic_msgs); | 68 | defer std.testing.allocator.free(expected_panic_msgs); |
| 72 | 69 | ||
| 73 | for (test_fns, names, async_frame_sizes, expected_panic_msgs) |test_fn, *name, *async_frame_size, *expected_panic_msg| { | 70 | for (test_fns, names, expected_panic_msgs) |test_fn, *name, *expected_panic_msg| { |
| 74 | name.* = @as(u32, @intCast(string_bytes.items.len)); | 71 | name.* = @as(u32, @intCast(string_bytes.items.len)); |
| 75 | try string_bytes.ensureUnusedCapacity(std.testing.allocator, test_fn.name.len + 1); | 72 | try string_bytes.ensureUnusedCapacity(std.testing.allocator, test_fn.name.len + 1); |
| 76 | string_bytes.appendSliceAssumeCapacity(test_fn.name); | 73 | string_bytes.appendSliceAssumeCapacity(test_fn.name); |
| 77 | string_bytes.appendAssumeCapacity(0); | 74 | string_bytes.appendAssumeCapacity(0); |
| 78 | |||
| 79 | async_frame_size.* = @as(u32, @intCast(test_fn.async_frame_size orelse 0)); | ||
| 80 | expected_panic_msg.* = 0; | 75 | expected_panic_msg.* = 0; |
| 81 | } | 76 | } |
| 82 | 77 | ||
| 83 | try server.serveTestMetadata(.{ | 78 | try server.serveTestMetadata(.{ |
| 84 | .names = names, | 79 | .names = names, |
| 85 | .async_frame_sizes = async_frame_sizes, | ||
| 86 | .expected_panic_msgs = expected_panic_msgs, | 80 | .expected_panic_msgs = expected_panic_msgs, |
| 87 | .string_bytes = string_bytes.items, | 81 | .string_bytes = string_bytes.items, |
| 88 | }); | 82 | }); |
| ... | @@ -93,8 +87,6 @@ fn mainServer() !void { | ... | @@ -93,8 +87,6 @@ fn mainServer() !void { |
| 93 | log_err_count = 0; | 87 | log_err_count = 0; |
| 94 | const index = try server.receiveBody_u32(); | 88 | const index = try server.receiveBody_u32(); |
| 95 | const test_fn = builtin.test_functions[index]; | 89 | const test_fn = builtin.test_functions[index]; |
| 96 | if (test_fn.async_frame_size != null) | ||
| 97 | @panic("TODO test runner implement async tests"); | ||
| 98 | var fail = false; | 90 | var fail = false; |
| 99 | var skip = false; | 91 | var skip = false; |
| 100 | var leak = false; | 92 | var leak = false; |
| ... | @@ -163,23 +155,7 @@ fn mainTerminal() void { | ... | @@ -163,23 +155,7 @@ fn mainTerminal() void { |
| 163 | if (!have_tty) { | 155 | if (!have_tty) { |
| 164 | std.debug.print("{d}/{d} {s}... ", .{ i + 1, test_fn_list.len, test_fn.name }); | 156 | std.debug.print("{d}/{d} {s}... ", .{ i + 1, test_fn_list.len, test_fn.name }); |
| 165 | } | 157 | } |
| 166 | const result = if (test_fn.async_frame_size) |size| switch (std.options.io_mode) { | 158 | if (test_fn.func()) |_| { |
| 167 | .evented => blk: { | ||
| 168 | if (async_frame_buffer.len < size) { | ||
| 169 | std.heap.page_allocator.free(async_frame_buffer); | ||
| 170 | async_frame_buffer = std.heap.page_allocator.alignedAlloc(u8, std.Target.stack_align, size) catch @panic("out of memory"); | ||
| 171 | } | ||
| 172 | const casted_fn = @as(fn () callconv(.Async) anyerror!void, @ptrCast(test_fn.func)); | ||
| 173 | break :blk await @asyncCall(async_frame_buffer, {}, casted_fn, .{}); | ||
| 174 | }, | ||
| 175 | .blocking => { | ||
| 176 | skip_count += 1; | ||
| 177 | test_node.end(); | ||
| 178 | progress.log("SKIP (async test)\n", .{}); | ||
| 179 | continue; | ||
| 180 | }, | ||
| 181 | } else test_fn.func(); | ||
| 182 | if (result) |_| { | ||
| 183 | ok_count += 1; | 159 | ok_count += 1; |
| 184 | test_node.end(); | 160 | test_node.end(); |
| 185 | if (!have_tty) std.debug.print("OK\n", .{}); | 161 | if (!have_tty) std.debug.print("OK\n", .{}); |
src/Builtin.zig-12| ... | @@ -3,7 +3,6 @@ zig_backend: std.builtin.CompilerBackend, | ... | @@ -3,7 +3,6 @@ zig_backend: std.builtin.CompilerBackend, |
| 3 | output_mode: std.builtin.OutputMode, | 3 | output_mode: std.builtin.OutputMode, |
| 4 | link_mode: std.builtin.LinkMode, | 4 | link_mode: std.builtin.LinkMode, |
| 5 | is_test: bool, | 5 | is_test: bool, |
| 6 | test_evented_io: bool, | ||
| 7 | single_threaded: bool, | 6 | single_threaded: bool, |
| 8 | link_libc: bool, | 7 | link_libc: bool, |
| 9 | link_libcpp: bool, | 8 | link_libcpp: bool, |
| ... | @@ -222,17 +221,6 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { | ... | @@ -222,17 +221,6 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 222 | \\pub var test_functions: []const std.builtin.TestFn = undefined; // overwritten later | 221 | \\pub var test_functions: []const std.builtin.TestFn = undefined; // overwritten later |
| 223 | \\ | 222 | \\ |
| 224 | ); | 223 | ); |
| 225 | if (opts.test_evented_io) { | ||
| 226 | try buffer.appendSlice( | ||
| 227 | \\pub const test_io_mode = .evented; | ||
| 228 | \\ | ||
| 229 | ); | ||
| 230 | } else { | ||
| 231 | try buffer.appendSlice( | ||
| 232 | \\pub const test_io_mode = .blocking; | ||
| 233 | \\ | ||
| 234 | ); | ||
| 235 | } | ||
| 236 | } | 224 | } |
| 237 | } | 225 | } |
| 238 | 226 |
src/Compilation.zig-2| ... | @@ -1607,7 +1607,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1607,7 +1607,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1607 | hash.add(options.config.use_lib_llvm); | 1607 | hash.add(options.config.use_lib_llvm); |
| 1608 | hash.add(options.config.dll_export_fns); | 1608 | hash.add(options.config.dll_export_fns); |
| 1609 | hash.add(options.config.is_test); | 1609 | hash.add(options.config.is_test); |
| 1610 | hash.add(options.config.test_evented_io); | ||
| 1611 | hash.addOptionalBytes(options.test_filter); | 1610 | hash.addOptionalBytes(options.test_filter); |
| 1612 | hash.addOptionalBytes(options.test_name_prefix); | 1611 | hash.addOptionalBytes(options.test_name_prefix); |
| 1613 | hash.add(options.skip_linker_dependencies); | 1612 | hash.add(options.skip_linker_dependencies); |
| ... | @@ -2471,7 +2470,6 @@ fn addNonIncrementalStuffToCacheManifest( | ... | @@ -2471,7 +2470,6 @@ fn addNonIncrementalStuffToCacheManifest( |
| 2471 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man }); | 2470 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man }); |
| 2472 | 2471 | ||
| 2473 | // Synchronize with other matching comments: ZigOnlyHashStuff | 2472 | // Synchronize with other matching comments: ZigOnlyHashStuff |
| 2474 | man.hash.add(comp.config.test_evented_io); | ||
| 2475 | man.hash.addOptionalBytes(comp.test_filter); | 2473 | man.hash.addOptionalBytes(comp.test_filter); |
| 2476 | man.hash.addOptionalBytes(comp.test_name_prefix); | 2474 | man.hash.addOptionalBytes(comp.test_name_prefix); |
| 2477 | man.hash.add(comp.skip_linker_dependencies); | 2475 | man.hash.add(comp.skip_linker_dependencies); |
src/Compilation/Config.zig-3| ... | @@ -54,7 +54,6 @@ import_memory: bool, | ... | @@ -54,7 +54,6 @@ import_memory: bool, |
| 54 | export_memory: bool, | 54 | export_memory: bool, |
| 55 | shared_memory: bool, | 55 | shared_memory: bool, |
| 56 | is_test: bool, | 56 | is_test: bool, |
| 57 | test_evented_io: bool, | ||
| 58 | debug_format: DebugFormat, | 57 | debug_format: DebugFormat, |
| 59 | root_strip: bool, | 58 | root_strip: bool, |
| 60 | root_error_tracing: bool, | 59 | root_error_tracing: bool, |
| ... | @@ -104,7 +103,6 @@ pub const Options = struct { | ... | @@ -104,7 +103,6 @@ pub const Options = struct { |
| 104 | import_memory: ?bool = null, | 103 | import_memory: ?bool = null, |
| 105 | export_memory: ?bool = null, | 104 | export_memory: ?bool = null, |
| 106 | shared_memory: ?bool = null, | 105 | shared_memory: ?bool = null, |
| 107 | test_evented_io: bool = false, | ||
| 108 | debug_format: ?DebugFormat = null, | 106 | debug_format: ?DebugFormat = null, |
| 109 | dll_export_fns: ?bool = null, | 107 | dll_export_fns: ?bool = null, |
| 110 | rdynamic: ?bool = null, | 108 | rdynamic: ?bool = null, |
| ... | @@ -477,7 +475,6 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -477,7 +475,6 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 477 | .output_mode = options.output_mode, | 475 | .output_mode = options.output_mode, |
| 478 | .have_zcu = options.have_zcu, | 476 | .have_zcu = options.have_zcu, |
| 479 | .is_test = options.is_test, | 477 | .is_test = options.is_test, |
| 480 | .test_evented_io = options.test_evented_io, | ||
| 481 | .link_mode = link_mode, | 478 | .link_mode = link_mode, |
| 482 | .link_libc = link_libc, | 479 | .link_libc = link_libc, |
| 483 | .link_libcpp = link_libcpp, | 480 | .link_libcpp = link_libcpp, |
src/Module.zig-6| ... | @@ -5237,10 +5237,6 @@ pub fn populateTestFunctions( | ... | @@ -5237,10 +5237,6 @@ pub fn populateTestFunctions( |
| 5237 | } | 5237 | } |
| 5238 | const decl = mod.declPtr(decl_index); | 5238 | const decl = mod.declPtr(decl_index); |
| 5239 | const test_fn_ty = decl.ty.slicePtrFieldType(mod).childType(mod); | 5239 | const test_fn_ty = decl.ty.slicePtrFieldType(mod).childType(mod); |
| 5240 | const null_usize = try mod.intern(.{ .opt = .{ | ||
| 5241 | .ty = try mod.intern(.{ .opt_type = .usize_type }), | ||
| 5242 | .val = .none, | ||
| 5243 | } }); | ||
| 5244 | 5240 | ||
| 5245 | const array_decl_index = d: { | 5241 | const array_decl_index = d: { |
| 5246 | // Add mod.test_functions to an array decl then make the test_functions | 5242 | // Add mod.test_functions to an array decl then make the test_functions |
| ... | @@ -5289,8 +5285,6 @@ pub fn populateTestFunctions( | ... | @@ -5289,8 +5285,6 @@ pub fn populateTestFunctions( |
| 5289 | } }), | 5285 | } }), |
| 5290 | .addr = .{ .decl = test_decl_index }, | 5286 | .addr = .{ .decl = test_decl_index }, |
| 5291 | } }), | 5287 | } }), |
| 5292 | // async_frame_size | ||
| 5293 | null_usize, | ||
| 5294 | }; | 5288 | }; |
| 5295 | test_fn_val.* = try mod.intern(.{ .aggregate = .{ | 5289 | test_fn_val.* = try mod.intern(.{ .aggregate = .{ |
| 5296 | .ty = test_fn_ty.toIntern(), | 5290 | .ty = test_fn_ty.toIntern(), |
src/Package/Module.zig-1| ... | @@ -349,7 +349,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { | ... | @@ -349,7 +349,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { |
| 349 | .output_mode = options.global.output_mode, | 349 | .output_mode = options.global.output_mode, |
| 350 | .link_mode = options.global.link_mode, | 350 | .link_mode = options.global.link_mode, |
| 351 | .is_test = options.global.is_test, | 351 | .is_test = options.global.is_test, |
| 352 | .test_evented_io = options.global.test_evented_io, | ||
| 353 | .single_threaded = single_threaded, | 352 | .single_threaded = single_threaded, |
| 354 | .link_libc = options.global.link_libc, | 353 | .link_libc = options.global.link_libc, |
| 355 | .link_libcpp = options.global.link_libcpp, | 354 | .link_libcpp = options.global.link_libcpp, |
src/main.zig-2| ... | @@ -1322,8 +1322,6 @@ fn buildOutputType( | ... | @@ -1322,8 +1322,6 @@ fn buildOutputType( |
| 1322 | create_module.each_lib_rpath = false; | 1322 | create_module.each_lib_rpath = false; |
| 1323 | } else if (mem.eql(u8, arg, "--test-cmd-bin")) { | 1323 | } else if (mem.eql(u8, arg, "--test-cmd-bin")) { |
| 1324 | try test_exec_args.append(null); | 1324 | try test_exec_args.append(null); |
| 1325 | } else if (mem.eql(u8, arg, "--test-evented-io")) { | ||
| 1326 | create_module.opts.test_evented_io = true; | ||
| 1327 | } else if (mem.eql(u8, arg, "--test-no-exec")) { | 1325 | } else if (mem.eql(u8, arg, "--test-no-exec")) { |
| 1328 | test_no_exec = true; | 1326 | test_no_exec = true; |
| 1329 | } else if (mem.eql(u8, arg, "-ftime-report")) { | 1327 | } else if (mem.eql(u8, arg, "-ftime-report")) { |