mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
std.Io.Threaded: implement netReceive for Windows
This commit is contained in:
+70
-5
@@ -13072,11 +13072,76 @@ fn netSendWindows(
|
||||
) struct { ?net.Socket.SendError, usize } {
|
||||
if (!have_networking) return .{ error.NetworkDown, 0 };
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
_ = t;
|
||||
_ = handle;
|
||||
_ = messages;
|
||||
_ = flags;
|
||||
@panic("TODO netSendWindows");
|
||||
|
||||
// Ignored flags: confirm, eor, fastopen
|
||||
const windows_flags: u32 =
|
||||
@as(u32, if (flags.oob) ws2_32.MSG.OOB else 0) |
|
||||
@as(u32, if (flags.dont_route) ws2_32.MSG.DONTROUTE else 0);
|
||||
|
||||
for (messages, 0..) |*m, i| {
|
||||
netSendWindowsOne(t, handle, m, windows_flags) catch |err| return .{ err, i };
|
||||
}
|
||||
return .{ null, messages.len };
|
||||
}
|
||||
|
||||
fn netSendWindowsOne(
|
||||
t: *Threaded,
|
||||
handle: net.Socket.Handle,
|
||||
message: *net.OutgoingMessage,
|
||||
flags: u32,
|
||||
) net.Socket.SendError!void {
|
||||
var buf: ws2_32.WSABUF = .{
|
||||
.buf = @constCast(message.data_ptr),
|
||||
.len = std.math.cast(u32, message.data_len) orelse return error.MessageOversize,
|
||||
};
|
||||
var n: u32 = undefined;
|
||||
var address: WsaAddress = undefined;
|
||||
const address_size = addressToWsa(message.address, &address);
|
||||
var syscall: Syscall = try .start();
|
||||
while (true) {
|
||||
const rc = ws2_32.WSASendTo(
|
||||
handle,
|
||||
(&buf)[0..1],
|
||||
1,
|
||||
&n,
|
||||
flags,
|
||||
&address.any,
|
||||
address_size,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
if (rc != ws2_32.SOCKET_ERROR) {
|
||||
syscall.finish();
|
||||
return;
|
||||
}
|
||||
switch (ws2_32.WSAGetLastError()) {
|
||||
.EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
|
||||
try syscall.checkCancel();
|
||||
continue;
|
||||
},
|
||||
.NOTINITIALISED => {
|
||||
syscall.finish();
|
||||
try initializeWsa(t);
|
||||
syscall = try .start();
|
||||
continue;
|
||||
},
|
||||
|
||||
.ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
|
||||
.ENETDOWN => return syscall.fail(error.NetworkDown),
|
||||
.ENETRESET => return syscall.fail(error.ConnectionResetByPeer),
|
||||
.ENOTCONN => return syscall.fail(error.SocketUnconnected),
|
||||
.EFAULT => unreachable, // a pointer is not completely contained in user address space.
|
||||
|
||||
else => |err| {
|
||||
syscall.finish();
|
||||
switch (err) {
|
||||
.EINVAL => return wsaErrorBug(err),
|
||||
.EMSGSIZE => return wsaErrorBug(err),
|
||||
else => return windows.unexpectedWSAError(err),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn netSendUnavailable(
|
||||
|
||||
+8
-7
@@ -1117,12 +1117,13 @@ pub const Socket = struct {
|
||||
/// * `receiveTimeout`
|
||||
pub fn receive(s: *const Socket, io: Io, buffer: []u8) ReceiveError!IncomingMessage {
|
||||
var message: IncomingMessage = .init;
|
||||
const maybe_err, const count = io.vtable.netReceive(io.userdata, s.handle, (&message)[0..1], buffer, .{}, .none);
|
||||
if (maybe_err) |err| switch (err) {
|
||||
// No timeout is passed to `netReceieve`, so it must not return timeout related errors.
|
||||
error.Timeout => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
const maybe_err, const count = (try io.operate(.{ .net_receive = .{
|
||||
.socket_handle = s.handle,
|
||||
.message_buffer = (&message)[0..1],
|
||||
.data_buffer = buffer,
|
||||
.flags = .{},
|
||||
} })).net_receive;
|
||||
if (maybe_err) |err| return err;
|
||||
assert(1 == count);
|
||||
return message;
|
||||
}
|
||||
@@ -1144,7 +1145,7 @@ pub const Socket = struct {
|
||||
) ReceiveTimeoutError!IncomingMessage {
|
||||
var message: IncomingMessage = .init;
|
||||
const maybe_err, const count = (try io.operateTimeout(.{ .net_receive = .{
|
||||
.socket = s.handle,
|
||||
.socket_handle = s.handle,
|
||||
.message_buffer = (&message)[0..1],
|
||||
.data_buffer = buffer,
|
||||
.flags = .{},
|
||||
|
||||
Reference in New Issue
Block a user