@@ -259,6 +259,7 @@ pub const Address = extern union {
259
259
/// Sets SO_REUSEADDR and SO_REUSEPORT on POSIX.
260
260
/// Sets SO_REUSEADDR on Windows, which is roughly equivalent.
261
261
reuse_address : bool = false ,
262
+ /// Sets O_NONBLOCK.
262
263
force_nonblocking : bool = false ,
263
264
};
264
265
@@ -1998,11 +1999,8 @@ pub const Stream = struct {
1998
1999
return n ;
1999
2000
}
2000
2001
2001
- fn streamBufs (r : * Reader , bufs : []windows.ws2_32.WSABUF ) Error ! u32 {
2002
- var n : u32 = undefined ;
2003
- var flags : u32 = 0 ;
2004
- const rc = windows .ws2_32 .WSARecvFrom (r .net_stream .handle , bufs .ptr , @intCast (bufs .len ), & n , & flags , null , null , null , null );
2005
- if (rc != 0 ) switch (windows .ws2_32 .WSAGetLastError ()) {
2002
+ fn handleRecvError (winsock_error : windows.ws2_32.WinsockError ) Error ! void {
2003
+ switch (winsock_error ) {
2006
2004
.WSAECONNRESET = > return error .ConnectionResetByPeer ,
2007
2005
.WSAEFAULT = > unreachable , // a pointer is not completely contained in user address space.
2008
2006
.WSAEINPROGRESS , .WSAEINTR = > unreachable , // deprecated and removed in WSA 2.2
@@ -2013,10 +2011,39 @@ pub const Stream = struct {
2013
2011
.WSAENOTCONN = > return error .SocketNotConnected ,
2014
2012
.WSAEWOULDBLOCK = > return error .WouldBlock ,
2015
2013
.WSANOTINITIALISED = > unreachable , // WSAStartup must be called before this function
2016
- .WSA_IO_PENDING = > unreachable , // not using overlapped I/O
2014
+ .WSA_IO_PENDING = > unreachable ,
2017
2015
.WSA_OPERATION_ABORTED = > unreachable , // not using overlapped I/O
2018
2016
else = > | err | return windows .unexpectedWSAError (err ),
2017
+ }
2018
+ }
2019
+
2020
+ fn streamBufs (r : * Reader , bufs : []windows.ws2_32.WSABUF ) Error ! u32 {
2021
+ var flags : u32 = 0 ;
2022
+ var overlapped : windows.OVERLAPPED = std .mem .zeroes (windows .OVERLAPPED );
2023
+
2024
+ var n : u32 = undefined ;
2025
+ if (windows .ws2_32 .WSARecv (
2026
+ r .net_stream .handle ,
2027
+ bufs .ptr ,
2028
+ @intCast (bufs .len ),
2029
+ & n ,
2030
+ & flags ,
2031
+ & overlapped ,
2032
+ null ,
2033
+ ) == windows .ws2_32 .SOCKET_ERROR ) switch (windows .ws2_32 .WSAGetLastError ()) {
2034
+ .WSA_IO_PENDING = > {
2035
+ var result_flags : u32 = undefined ;
2036
+ if (windows .ws2_32 .WSAGetOverlappedResult (
2037
+ r .net_stream .handle ,
2038
+ & overlapped ,
2039
+ & n ,
2040
+ windows .TRUE ,
2041
+ & result_flags ,
2042
+ ) == windows .FALSE ) try handleRecvError (windows .ws2_32 .WSAGetLastError ());
2043
+ },
2044
+ else = > | winsock_error | try handleRecvError (winsock_error ),
2019
2045
};
2046
+
2020
2047
return n ;
2021
2048
}
2022
2049
},
@@ -2136,10 +2163,8 @@ pub const Stream = struct {
2136
2163
return io_w .consume (n );
2137
2164
}
2138
2165
2139
- fn sendBufs (handle : Stream.Handle , bufs : []windows.ws2_32.WSABUF ) Error ! u32 {
2140
- var n : u32 = undefined ;
2141
- const rc = windows .ws2_32 .WSASend (handle , bufs .ptr , @intCast (bufs .len ), & n , 0 , null , null );
2142
- if (rc == windows .ws2_32 .SOCKET_ERROR ) switch (windows .ws2_32 .WSAGetLastError ()) {
2166
+ fn handleSendError (winsock_error : windows.ws2_32.WinsockError ) Error ! void {
2167
+ switch (winsock_error ) {
2143
2168
.WSAECONNABORTED = > return error .ConnectionResetByPeer ,
2144
2169
.WSAECONNRESET = > return error .ConnectionResetByPeer ,
2145
2170
.WSAEFAULT = > unreachable , // a pointer is not completely contained in user address space.
@@ -2155,10 +2180,37 @@ pub const Stream = struct {
2155
2180
.WSAESHUTDOWN = > unreachable , // cannot send on a socket after write shutdown
2156
2181
.WSAEWOULDBLOCK = > return error .WouldBlock ,
2157
2182
.WSANOTINITIALISED = > unreachable , // WSAStartup must be called before this function
2158
- .WSA_IO_PENDING = > unreachable , // not using overlapped I/O
2183
+ .WSA_IO_PENDING = > unreachable ,
2159
2184
.WSA_OPERATION_ABORTED = > unreachable , // not using overlapped I/O
2160
2185
else = > | err | return windows .unexpectedWSAError (err ),
2186
+ }
2187
+ }
2188
+
2189
+ fn sendBufs (handle : Stream.Handle , bufs : []windows.ws2_32.WSABUF ) Error ! u32 {
2190
+ var n : u32 = undefined ;
2191
+ var overlapped : windows.OVERLAPPED = std .mem .zeroes (windows .OVERLAPPED );
2192
+ if (windows .ws2_32 .WSASend (
2193
+ handle ,
2194
+ bufs .ptr ,
2195
+ @intCast (bufs .len ),
2196
+ & n ,
2197
+ 0 ,
2198
+ & overlapped ,
2199
+ null ,
2200
+ ) == windows .ws2_32 .SOCKET_ERROR ) switch (windows .ws2_32 .WSAGetLastError ()) {
2201
+ .WSA_IO_PENDING = > {
2202
+ var result_flags : u32 = undefined ;
2203
+ if (windows .ws2_32 .WSAGetOverlappedResult (
2204
+ handle ,
2205
+ & overlapped ,
2206
+ & n ,
2207
+ windows .TRUE ,
2208
+ & result_flags ,
2209
+ ) == windows .FALSE ) try handleSendError (windows .ws2_32 .WSAGetLastError ());
2210
+ },
2211
+ else = > | winsock_error | try handleSendError (winsock_error ),
2161
2212
};
2213
+
2162
2214
return n ;
2163
2215
}
2164
2216
},
0 commit comments