From c4d9d65a7bfb0e675ff9b43c50332032bcec6b25 Mon Sep 17 00:00:00 2001 From: hemisputnik Date: Wed, 22 Jul 2026 11:28:31 +0300 Subject: [PATCH] std.Io.net: send control data with .net_write Add a new parameter to .net_write - control. --- lib/std/Io.zig | 1 + lib/std/Io/Threaded.zig | 15 ++++++++++----- lib/std/Io/net.zig | 4 ++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/std/Io.zig b/lib/std/Io.zig index e7bef51fce5b8160af6b5d1deef4869edd6e594a..ab0f8514b407cb567c048db502eb3b52d4a27fd4 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -453,6 +453,7 @@ pub const Operation = union(enum) { header: []const u8 = &.{}, data: []const []const u8, splat: usize = 1, + control: []const u8 = &.{}, pub const Error = error{ /// Another TCP Fast Open is already in progress. diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 4ae0a35668728c0a17b1708d6cba113dfe843e60..77f14f6f991faa3ec821c8ad784445f1c2dd8d09 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -2590,9 +2590,9 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper }, .net_write => |o| return .{ .net_write = (if (is_windows) - netWriteWindows(o.socket_handle, o.header, o.data, o.splat) + netWriteWindows(o.socket_handle, o.header, o.data, o.splat, o.control) else - netWritePosix(o.socket_handle, o.header, o.data, o.splat)) catch |err| switch (err) { + netWritePosix(o.socket_handle, o.header, o.data, o.splat, o.control)) catch |err| switch (err) { error.Canceled => |e| return e, else => |e| e, }, @@ -3306,7 +3306,7 @@ fn batchDrainSubmittedWindows(t: *Threaded, b: *Io.Batch, concurrency: bool) (Io // TODO integrate with overlapped I/O or equivalent to avoid this error if (concurrency) return error.ConcurrencyUnavailable; batchCompleteBlockingWindows(b, operation_userdata, .{ - .net_write = netWriteWindows(o.socket_handle, o.header, o.data, o.splat) catch |err| switch (err) { + .net_write = netWriteWindows(o.socket_handle, o.header, o.data, o.splat, o.control) catch |err| switch (err) { error.Canceled => |e| return e, else => |e| e, }, @@ -13389,6 +13389,7 @@ fn netWritePosix( header: []const u8, data: []const []const u8, splat: usize, + control: []const u8, ) net.Stream.Writer.Error!usize { if (!have_networking) return error.NetworkDown; @@ -13398,8 +13399,8 @@ fn netWritePosix( .namelen = 0, .iov = &iovecs, .iovlen = 0, - .control = null, - .controllen = 0, + .control = if (control.len == 0) null else @constCast(control.ptr), + .controllen = @intCast(control.len), .flags = 0, }; addBuf(&iovecs, &msg.iovlen, header); @@ -13481,9 +13482,13 @@ fn netWriteWindows( header: []const u8, data: []const []const u8, splat: usize, + control: []const u8, ) net.Stream.Writer.Error!usize { if (!have_networking) return error.NetworkDown; + // Windows doesn't have the concept of control/ancillary data. + _ = control; + var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"const") = undefined; var len: u32 = 0; addAfdBuf(.@"const", &iovecs, &len, header); diff --git a/lib/std/Io/net.zig b/lib/std/Io/net.zig index 82bbcc0e707836d807cc5f7dea739f0668a583b5..01547a1a9df1c53ffdac6a370f2108136d6b6af2 100644 --- a/lib/std/Io/net.zig +++ b/lib/std/Io/net.zig @@ -1457,6 +1457,8 @@ pub const Stream = struct { pub const Writer = struct { io: Io, interface: Io.Writer, + /// Will be sent on next drain, then set back to an empty slice. + control: []const u8 = &.{}, stream: Stream, err: ?Error = null, write_file_err: ?WriteFileError = null, @@ -1499,6 +1501,7 @@ pub const Stream = struct { .header = buffered, .data = data, .splat = splat, + .control = w.control, } }) catch |err| { w.err = err; return error.WriteFailed; @@ -1507,6 +1510,7 @@ pub const Stream = struct { w.err = err; return error.WriteFailed; }; + w.control = &.{}; return io_w.consume(n); } -- 2.54.0