| ... | @@ -13072,11 +13072,76 @@ fn netSendWindows( | ... | @@ -13072,11 +13072,76 @@ fn netSendWindows( |
| 13072 | ) struct { ?net.Socket.SendError, usize } { | 13072 | ) struct { ?net.Socket.SendError, usize } { |
| 13073 | if (!have_networking) return .{ error.NetworkDown, 0 }; | 13073 | if (!have_networking) return .{ error.NetworkDown, 0 }; |
| 13074 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 13074 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 13075 | _ = t; | 13075 | |
| 13076 | _ = handle; | 13076 | // Ignored flags: confirm, eor, fastopen |
| 13077 | _ = messages; | 13077 | const windows_flags: u32 = |
| 13078 | _ = flags; | 13078 | @as(u32, if (flags.oob) ws2_32.MSG.OOB else 0) | |
| 13079 | @panic("TODO netSendWindows"); | 13079 | @as(u32, if (flags.dont_route) ws2_32.MSG.DONTROUTE else 0); |
| | 13080 | |
| | 13081 | for (messages, 0..) |*m, i| { |
| | 13082 | netSendWindowsOne(t, handle, m, windows_flags) catch |err| return .{ err, i }; |
| | 13083 | } |
| | 13084 | return .{ null, messages.len }; |
| | 13085 | } |
| | 13086 | |
| | 13087 | fn netSendWindowsOne( |
| | 13088 | t: *Threaded, |
| | 13089 | handle: net.Socket.Handle, |
| | 13090 | message: *net.OutgoingMessage, |
| | 13091 | flags: u32, |
| | 13092 | ) net.Socket.SendError!void { |
| | 13093 | var buf: ws2_32.WSABUF = .{ |
| | 13094 | .buf = @constCast(message.data_ptr), |
| | 13095 | .len = std.math.cast(u32, message.data_len) orelse return error.MessageOversize, |
| | 13096 | }; |
| | 13097 | var n: u32 = undefined; |
| | 13098 | var address: WsaAddress = undefined; |
| | 13099 | const address_size = addressToWsa(message.address, &address); |
| | 13100 | var syscall: Syscall = try .start(); |
| | 13101 | while (true) { |
| | 13102 | const rc = ws2_32.WSASendTo( |
| | 13103 | handle, |
| | 13104 | (&buf)[0..1], |
| | 13105 | 1, |
| | 13106 | &n, |
| | 13107 | flags, |
| | 13108 | &address.any, |
| | 13109 | address_size, |
| | 13110 | null, |
| | 13111 | null, |
| | 13112 | ); |
| | 13113 | if (rc != ws2_32.SOCKET_ERROR) { |
| | 13114 | syscall.finish(); |
| | 13115 | return; |
| | 13116 | } |
| | 13117 | switch (ws2_32.WSAGetLastError()) { |
| | 13118 | .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => { |
| | 13119 | try syscall.checkCancel(); |
| | 13120 | continue; |
| | 13121 | }, |
| | 13122 | .NOTINITIALISED => { |
| | 13123 | syscall.finish(); |
| | 13124 | try initializeWsa(t); |
| | 13125 | syscall = try .start(); |
| | 13126 | continue; |
| | 13127 | }, |
| | 13128 | |
| | 13129 | .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer), |
| | 13130 | .ENETDOWN => return syscall.fail(error.NetworkDown), |
| | 13131 | .ENETRESET => return syscall.fail(error.ConnectionResetByPeer), |
| | 13132 | .ENOTCONN => return syscall.fail(error.SocketUnconnected), |
| | 13133 | .EFAULT => unreachable, // a pointer is not completely contained in user address space. |
| | 13134 | |
| | 13135 | else => |err| { |
| | 13136 | syscall.finish(); |
| | 13137 | switch (err) { |
| | 13138 | .EINVAL => return wsaErrorBug(err), |
| | 13139 | .EMSGSIZE => return wsaErrorBug(err), |
| | 13140 | else => return windows.unexpectedWSAError(err), |
| | 13141 | } |
| | 13142 | }, |
| | 13143 | } |
| | 13144 | } |
| 13080 | } | 13145 | } |
| 13081 | | 13146 | |
| 13082 | fn netSendUnavailable( | 13147 | fn netSendUnavailable( |