mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
std.Io.net: make netSend support multiple messages
this lowers to sendmmsg on linux, and means Io.Group is no longer needed, resulting in a more efficient implementation.
This commit is contained in:
parent
46e5068e48
commit
47f18ee6a0
4 changed files with 39 additions and 15 deletions
|
|
@ -671,7 +671,7 @@ pub const VTable = struct {
|
|||
listen: *const fn (?*anyopaque, address: net.IpAddress, options: net.IpAddress.ListenOptions) net.IpAddress.ListenError!net.Server,
|
||||
accept: *const fn (?*anyopaque, server: *net.Server) net.Server.AcceptError!net.Stream,
|
||||
ipBind: *const fn (?*anyopaque, address: net.IpAddress, options: net.IpAddress.BindOptions) net.IpAddress.BindError!net.Socket,
|
||||
netSend: *const fn (?*anyopaque, handle: net.Socket.Handle, address: *const net.IpAddress, data: []const u8) net.Socket.SendError!void,
|
||||
netSend: *const fn (?*anyopaque, net.Socket.Handle, []const net.OutgoingMessage, net.SendFlags) net.Socket.SendError!void,
|
||||
netReceive: *const fn (?*anyopaque, handle: net.Socket.Handle, buffer: []u8, timeout: Timeout) net.Socket.ReceiveTimeoutError!net.ReceivedMessage,
|
||||
netRead: *const fn (?*anyopaque, src: net.Stream, data: [][]u8) net.Stream.Reader.Error!usize,
|
||||
netWrite: *const fn (?*anyopaque, dest: net.Stream, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize,
|
||||
|
|
|
|||
|
|
@ -1309,15 +1309,15 @@ fn netReadPosix(userdata: ?*anyopaque, stream: Io.net.Stream, data: [][]u8) Io.n
|
|||
fn netSend(
|
||||
userdata: ?*anyopaque,
|
||||
handle: Io.net.Socket.Handle,
|
||||
address: *const Io.net.IpAddress,
|
||||
data: []const u8,
|
||||
messages: []const Io.net.OutgoingMessage,
|
||||
flags: Io.net.SendFlags,
|
||||
) Io.net.Socket.SendError!void {
|
||||
const pool: *Pool = @ptrCast(@alignCast(userdata));
|
||||
try pool.checkCancel();
|
||||
|
||||
_ = handle;
|
||||
_ = address;
|
||||
_ = data;
|
||||
_ = messages;
|
||||
_ = flags;
|
||||
@panic("TODO");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -700,6 +700,21 @@ pub const ReceivedMessage = struct {
|
|||
len: usize,
|
||||
};
|
||||
|
||||
pub const OutgoingMessage = struct {
|
||||
address: *const IpAddress,
|
||||
data: []const u8,
|
||||
control: []const u8 = &.{},
|
||||
};
|
||||
|
||||
pub const SendFlags = packed struct(u8) {
|
||||
confirm: bool = false,
|
||||
dont_route: bool = false,
|
||||
eor: bool = false,
|
||||
oob: bool = false,
|
||||
fastopen: bool = false,
|
||||
_: u3 = 0,
|
||||
};
|
||||
|
||||
pub const Interface = struct {
|
||||
/// Value 0 indicates `none`.
|
||||
index: u32,
|
||||
|
|
@ -818,7 +833,12 @@ pub const Socket = struct {
|
|||
|
||||
/// Transfers `data` to `dest`, connectionless.
|
||||
pub fn send(s: *const Socket, io: Io, dest: *const IpAddress, data: []const u8) SendError!void {
|
||||
return io.vtable.netSend(io.userdata, s.handle, dest, data);
|
||||
const message: OutgoingMessage = .{ .address = dest, .data = data };
|
||||
return io.vtable.netSend(io.userdata, s.handle, &.{message}, .{});
|
||||
}
|
||||
|
||||
pub fn sendMany(s: *const Socket, io: Io, messages: []const OutgoingMessage, flags: SendFlags) SendError!void {
|
||||
return io.vtable.netSend(io.userdata, s.handle, messages, flags);
|
||||
}
|
||||
|
||||
pub const ReceiveError = error{} || Io.UnexpectedError || Io.Cancelable;
|
||||
|
|
|
|||
|
|
@ -271,15 +271,19 @@ fn lookupDns(io: Io, lookup_canon_name: []const u8, rc: *const ResolvConf, optio
|
|||
};
|
||||
|
||||
send: while (now_ts.compare(.lt, final_ts)) : (now_ts = try io.now(.MONOTONIC)) {
|
||||
var group: Io.Group = .init;
|
||||
defer group.cancel(io);
|
||||
|
||||
var message_buffer: [queries_buffer.len * ResolvConf.max_nameservers]Io.net.OutgoingMessage = undefined;
|
||||
var message_i: usize = 0;
|
||||
for (queries, answers) |query, *answer| {
|
||||
if (answer.len != 0) continue;
|
||||
for (mapped_nameservers) |*ns| {
|
||||
group.async(io, sendIgnoringResult, .{ io, socket.handle, ns, query });
|
||||
message_buffer[message_i] = .{
|
||||
.address = ns,
|
||||
.data = query,
|
||||
};
|
||||
message_i += 1;
|
||||
}
|
||||
}
|
||||
io.vtable.netSend(io.userdata, socket.handle, message_buffer[0..message_i], .{}) catch {};
|
||||
|
||||
const timeout: Io.Timeout = .{ .deadline = now_ts.addDuration(attempt_duration) };
|
||||
|
||||
|
|
@ -320,7 +324,11 @@ fn lookupDns(io: Io, lookup_canon_name: []const u8, rc: *const ResolvConf, optio
|
|||
if (next_answer_buffer == answers.len) break :send;
|
||||
},
|
||||
2 => {
|
||||
group.async(io, sendIgnoringResult, .{ io, socket.handle, ns, query });
|
||||
const message: Io.net.OutgoingMessage = .{
|
||||
.address = ns,
|
||||
.data = query,
|
||||
};
|
||||
io.vtable.netSend(io.userdata, socket.handle, &.{message}, .{}) catch {};
|
||||
continue;
|
||||
},
|
||||
else => continue,
|
||||
|
|
@ -382,10 +390,6 @@ fn lookupDns(io: Io, lookup_canon_name: []const u8, rc: *const ResolvConf, optio
|
|||
return error.NameServerFailure;
|
||||
}
|
||||
|
||||
fn sendIgnoringResult(io: Io, socket_handle: Io.net.Socket.Handle, dest: *const IpAddress, msg: []const u8) void {
|
||||
_ = io.vtable.netSend(io.userdata, socket_handle, dest, msg) catch {};
|
||||
}
|
||||
|
||||
fn lookupHosts(host_name: HostName, io: Io, options: LookupOptions) !LookupResult {
|
||||
const file = Io.File.openAbsolute(io, "/etc/hosts", .{}) catch |err| switch (err) {
|
||||
error.FileNotFound,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue