authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-26 12:04:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:51-07:00
log6cff32c7ee5be4e10ea768a20c724e348fc90ba3
treec2d0f44c58bebb95438785f54229a6767dfd1c79
parenta8f95e5176ebd734ccd2fd4d92cced6ab4cc2c07

std.Io.Threaded: implement netRead for Windows


1 files changed, 80 insertions(+), 14 deletions(-)

lib/std/Io/Threaded.zig+80-14
......@@ -2976,7 +2976,7 @@ fn netListenIpWindows(
29762976 if (rc != ws2_32.SOCKET_ERROR) break;
29772977 switch (ws2_32.WSAGetLastError()) {
29782978 .EINTR => continue,
2979 .ECANCELLED, .E_CANCELLED => return error.Canceled,
2979 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
29802980 .NOTINITIALISED => {
29812981 try initializeWsa(t);
29822982 continue;
......@@ -2998,7 +2998,7 @@ fn netListenIpWindows(
29982998 if (rc != ws2_32.SOCKET_ERROR) break;
29992999 switch (ws2_32.WSAGetLastError()) {
30003000 .EINTR => continue,
3001 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3001 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
30023002 .NOTINITIALISED => {
30033003 try initializeWsa(t);
30043004 continue;
......@@ -3231,7 +3231,7 @@ fn wsaGetSockName(t: *Threaded, handle: ws2_32.SOCKET, addr: *ws2_32.sockaddr, a
32313231 if (rc != ws2_32.SOCKET_ERROR) break;
32323232 switch (ws2_32.WSAGetLastError()) {
32333233 .EINTR => continue,
3234 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3234 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
32353235 .NOTINITIALISED => {
32363236 try initializeWsa(t);
32373237 continue;
......@@ -3270,7 +3270,7 @@ fn setSocketOptionWsa(t: *Threaded, socket: Io.net.Socket.Handle, level: i32, op
32703270 if (rc != ws2_32.SOCKET_ERROR) return;
32713271 switch (ws2_32.WSAGetLastError()) {
32723272 .EINTR => continue,
3273 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3273 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
32743274 .NOTINITIALISED => {
32753275 try initializeWsa(t);
32763276 continue;
......@@ -3331,7 +3331,7 @@ fn netConnectIpWindows(
33313331 if (rc != ws2_32.SOCKET_ERROR) break;
33323332 switch (ws2_32.WSAGetLastError()) {
33333333 .EINTR => continue,
3334 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3334 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
33353335 .NOTINITIALISED => {
33363336 try initializeWsa(t);
33373337 continue;
......@@ -3454,7 +3454,7 @@ fn netBindIpWindows(
34543454 if (rc != ws2_32.SOCKET_ERROR) break;
34553455 switch (ws2_32.WSAGetLastError()) {
34563456 .EINTR => continue,
3457 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3457 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
34583458 .NOTINITIALISED => {
34593459 try initializeWsa(t);
34603460 continue;
......@@ -3560,7 +3560,7 @@ fn openSocketWsa(t: *Threaded, family: posix.sa_family_t, options: IpAddress.Bin
35603560 if (rc != ws2_32.INVALID_SOCKET) return rc;
35613561 switch (ws2_32.WSAGetLastError()) {
35623562 .EINTR => continue,
3563 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3563 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
35643564 .NOTINITIALISED => {
35653565 try initializeWsa(t);
35663566 continue;
......@@ -3639,7 +3639,7 @@ fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net
36393639 } };
36403640 switch (ws2_32.WSAGetLastError()) {
36413641 .EINTR => continue,
3642 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3642 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
36433643 .NOTINITIALISED => {
36443644 try initializeWsa(t);
36453645 continue;
......@@ -3728,10 +3728,76 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
37283728fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
37293729 if (!have_networking) return error.NetworkDown;
37303730 const t: *Threaded = @ptrCast(@alignCast(userdata));
3731 _ = t;
3732 _ = handle;
3733 _ = data;
3734 @panic("TODO implement netReadWindows");
3731
3732 const bufs = b: {
3733 var iovec_buffer: [max_iovecs_len]ws2_32.WSABUF = undefined;
3734 var i: usize = 0;
3735 var n: usize = 0;
3736 for (data) |buf| {
3737 if (iovec_buffer.len - i == 0) break;
3738 if (buf.len == 0) continue;
3739 if (std.math.cast(u32, buf.len)) |len| {
3740 iovec_buffer[i] = .{ .buf = buf.ptr, .len = len };
3741 i += 1;
3742 n += len;
3743 continue;
3744 }
3745 iovec_buffer[i] = .{ .buf = buf.ptr, .len = std.math.maxInt(u32) };
3746 i += 1;
3747 n += std.math.maxInt(u32);
3748 break;
3749 }
3750
3751 const bufs = iovec_buffer[0..i];
3752 assert(bufs[0].len != 0);
3753
3754 break :b bufs;
3755 };
3756
3757 while (true) {
3758 try t.checkCancel();
3759
3760 var flags: u32 = 0;
3761 var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);
3762 var n: u32 = undefined;
3763 const rc = ws2_32.WSARecv(handle, bufs.ptr, @intCast(bufs.len), &n, &flags, &overlapped, null);
3764 if (rc != ws2_32.SOCKET_ERROR) return n;
3765 const wsa_error: ws2_32.WinsockError = switch (ws2_32.WSAGetLastError()) {
3766 .IO_PENDING => e: {
3767 var result_flags: u32 = undefined;
3768 const overlapped_rc = ws2_32.WSAGetOverlappedResult(
3769 handle,
3770 &overlapped,
3771 &n,
3772 windows.TRUE,
3773 &result_flags,
3774 );
3775 if (overlapped_rc == windows.FALSE) {
3776 break :e ws2_32.WSAGetLastError();
3777 } else {
3778 return n;
3779 }
3780 },
3781 else => |err| err,
3782 };
3783 switch (wsa_error) {
3784 .EINTR => continue,
3785 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3786 .NOTINITIALISED => {
3787 try initializeWsa(t);
3788 continue;
3789 },
3790
3791 .ECONNRESET => return error.ConnectionResetByPeer,
3792 .EFAULT => unreachable, // a pointer is not completely contained in user address space.
3793 .EINVAL => |err| return wsaErrorBug(err),
3794 .EMSGSIZE => |err| return wsaErrorBug(err),
3795 .ENETDOWN => return error.NetworkDown,
3796 .ENETRESET => return error.ConnectionResetByPeer,
3797 .ENOTCONN => return error.SocketUnconnected,
3798 else => |err| return windows.unexpectedWSAError(err),
3799 }
3800 }
37353801}
37363802
37373803fn netReadUnavailable(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
......@@ -3823,7 +3889,7 @@ fn netSendOne(
38233889 if (rc == ws2_32.SOCKET_ERROR) {
38243890 switch (ws2_32.WSAGetLastError()) {
38253891 .EINTR => continue,
3826 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3892 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
38273893 .NOTINITIALISED => {
38283894 try initializeWsa(t);
38293895 continue;
......@@ -4422,7 +4488,7 @@ fn netLookupFallible(
44224488 switch (rc) {
44234489 @as(ws2_32.WinsockError, @enumFromInt(0)) => break,
44244490 .EINTR => continue,
4425 .ECANCELLED, .E_CANCELLED => return error.Canceled,
4491 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
44264492 .NOTINITIALISED => {
44274493 try initializeWsa(t);
44284494 continue;