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(...@@ -2976,7 +2976,7 @@ fn netListenIpWindows(
2976 if (rc != ws2_32.SOCKET_ERROR) break;2976 if (rc != ws2_32.SOCKET_ERROR) break;
2977 switch (ws2_32.WSAGetLastError()) {2977 switch (ws2_32.WSAGetLastError()) {
2978 .EINTR => continue,2978 .EINTR => continue,
2979 .ECANCELLED, .E_CANCELLED => return error.Canceled,2979 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
2980 .NOTINITIALISED => {2980 .NOTINITIALISED => {
2981 try initializeWsa(t);2981 try initializeWsa(t);
2982 continue;2982 continue;
...@@ -2998,7 +2998,7 @@ fn netListenIpWindows(...@@ -2998,7 +2998,7 @@ fn netListenIpWindows(
2998 if (rc != ws2_32.SOCKET_ERROR) break;2998 if (rc != ws2_32.SOCKET_ERROR) break;
2999 switch (ws2_32.WSAGetLastError()) {2999 switch (ws2_32.WSAGetLastError()) {
3000 .EINTR => continue,3000 .EINTR => continue,
3001 .ECANCELLED, .E_CANCELLED => return error.Canceled,3001 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3002 .NOTINITIALISED => {3002 .NOTINITIALISED => {
3003 try initializeWsa(t);3003 try initializeWsa(t);
3004 continue;3004 continue;
...@@ -3231,7 +3231,7 @@ fn wsaGetSockName(t: *Threaded, handle: ws2_32.SOCKET, addr: *ws2_32.sockaddr, a...@@ -3231,7 +3231,7 @@ fn wsaGetSockName(t: *Threaded, handle: ws2_32.SOCKET, addr: *ws2_32.sockaddr, a
3231 if (rc != ws2_32.SOCKET_ERROR) break;3231 if (rc != ws2_32.SOCKET_ERROR) break;
3232 switch (ws2_32.WSAGetLastError()) {3232 switch (ws2_32.WSAGetLastError()) {
3233 .EINTR => continue,3233 .EINTR => continue,
3234 .ECANCELLED, .E_CANCELLED => return error.Canceled,3234 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3235 .NOTINITIALISED => {3235 .NOTINITIALISED => {
3236 try initializeWsa(t);3236 try initializeWsa(t);
3237 continue;3237 continue;
...@@ -3270,7 +3270,7 @@ fn setSocketOptionWsa(t: *Threaded, socket: Io.net.Socket.Handle, level: i32, op...@@ -3270,7 +3270,7 @@ fn setSocketOptionWsa(t: *Threaded, socket: Io.net.Socket.Handle, level: i32, op
3270 if (rc != ws2_32.SOCKET_ERROR) return;3270 if (rc != ws2_32.SOCKET_ERROR) return;
3271 switch (ws2_32.WSAGetLastError()) {3271 switch (ws2_32.WSAGetLastError()) {
3272 .EINTR => continue,3272 .EINTR => continue,
3273 .ECANCELLED, .E_CANCELLED => return error.Canceled,3273 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3274 .NOTINITIALISED => {3274 .NOTINITIALISED => {
3275 try initializeWsa(t);3275 try initializeWsa(t);
3276 continue;3276 continue;
...@@ -3331,7 +3331,7 @@ fn netConnectIpWindows(...@@ -3331,7 +3331,7 @@ fn netConnectIpWindows(
3331 if (rc != ws2_32.SOCKET_ERROR) break;3331 if (rc != ws2_32.SOCKET_ERROR) break;
3332 switch (ws2_32.WSAGetLastError()) {3332 switch (ws2_32.WSAGetLastError()) {
3333 .EINTR => continue,3333 .EINTR => continue,
3334 .ECANCELLED, .E_CANCELLED => return error.Canceled,3334 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3335 .NOTINITIALISED => {3335 .NOTINITIALISED => {
3336 try initializeWsa(t);3336 try initializeWsa(t);
3337 continue;3337 continue;
...@@ -3454,7 +3454,7 @@ fn netBindIpWindows(...@@ -3454,7 +3454,7 @@ fn netBindIpWindows(
3454 if (rc != ws2_32.SOCKET_ERROR) break;3454 if (rc != ws2_32.SOCKET_ERROR) break;
3455 switch (ws2_32.WSAGetLastError()) {3455 switch (ws2_32.WSAGetLastError()) {
3456 .EINTR => continue,3456 .EINTR => continue,
3457 .ECANCELLED, .E_CANCELLED => return error.Canceled,3457 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3458 .NOTINITIALISED => {3458 .NOTINITIALISED => {
3459 try initializeWsa(t);3459 try initializeWsa(t);
3460 continue;3460 continue;
...@@ -3560,7 +3560,7 @@ fn openSocketWsa(t: *Threaded, family: posix.sa_family_t, options: IpAddress.Bin...@@ -3560,7 +3560,7 @@ fn openSocketWsa(t: *Threaded, family: posix.sa_family_t, options: IpAddress.Bin
3560 if (rc != ws2_32.INVALID_SOCKET) return rc;3560 if (rc != ws2_32.INVALID_SOCKET) return rc;
3561 switch (ws2_32.WSAGetLastError()) {3561 switch (ws2_32.WSAGetLastError()) {
3562 .EINTR => continue,3562 .EINTR => continue,
3563 .ECANCELLED, .E_CANCELLED => return error.Canceled,3563 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3564 .NOTINITIALISED => {3564 .NOTINITIALISED => {
3565 try initializeWsa(t);3565 try initializeWsa(t);
3566 continue;3566 continue;
...@@ -3639,7 +3639,7 @@ fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net...@@ -3639,7 +3639,7 @@ fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net
3639 } };3639 } };
3640 switch (ws2_32.WSAGetLastError()) {3640 switch (ws2_32.WSAGetLastError()) {
3641 .EINTR => continue,3641 .EINTR => continue,
3642 .ECANCELLED, .E_CANCELLED => return error.Canceled,3642 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3643 .NOTINITIALISED => {3643 .NOTINITIALISED => {
3644 try initializeWsa(t);3644 try initializeWsa(t);
3645 continue;3645 continue;
...@@ -3728,10 +3728,76 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -3728,10 +3728,76 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
3728fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {3728fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
3729 if (!have_networking) return error.NetworkDown;3729 if (!have_networking) return error.NetworkDown;
3730 const t: *Threaded = @ptrCast(@alignCast(userdata));3730 const t: *Threaded = @ptrCast(@alignCast(userdata));
3731 _ = t;3731
3732 _ = handle;3732 const bufs = b: {
3733 _ = data;3733 var iovec_buffer: [max_iovecs_len]ws2_32.WSABUF = undefined;
3734 @panic("TODO implement netReadWindows");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 }
3735}3801}
37363802
3737fn netReadUnavailable(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {3803fn netReadUnavailable(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
...@@ -3823,7 +3889,7 @@ fn netSendOne(...@@ -3823,7 +3889,7 @@ fn netSendOne(
3823 if (rc == ws2_32.SOCKET_ERROR) {3889 if (rc == ws2_32.SOCKET_ERROR) {
3824 switch (ws2_32.WSAGetLastError()) {3890 switch (ws2_32.WSAGetLastError()) {
3825 .EINTR => continue,3891 .EINTR => continue,
3826 .ECANCELLED, .E_CANCELLED => return error.Canceled,3892 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3827 .NOTINITIALISED => {3893 .NOTINITIALISED => {
3828 try initializeWsa(t);3894 try initializeWsa(t);
3829 continue;3895 continue;
...@@ -4422,7 +4488,7 @@ fn netLookupFallible(...@@ -4422,7 +4488,7 @@ fn netLookupFallible(
4422 switch (rc) {4488 switch (rc) {
4423 @as(ws2_32.WinsockError, @enumFromInt(0)) => break,4489 @as(ws2_32.WinsockError, @enumFromInt(0)) => break,
4424 .EINTR => continue,4490 .EINTR => continue,
4425 .ECANCELLED, .E_CANCELLED => return error.Canceled,4491 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
4426 .NOTINITIALISED => {4492 .NOTINITIALISED => {
4427 try initializeWsa(t);4493 try initializeWsa(t);
4428 continue;4494 continue;