authorgravatar for lukas@lalinsky.comLukas Lalinsky <lukas@lalinsky.com> 2026-05-12 11:50:22+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-11 11:57:57+02:00
log9d92d2ce93c52083fe405716a6cf05151384b76e
tree13c48aa35738f4604330037d64ec4f66c4adad06
parent254c23b03875387798b8ce779223091c5f6ee444

Migrate `netWrite` to `std.Io.Operation`

Preparation for adding timeouts: https://codeberg.org/ziglang/zig/issues/32166

6 files changed, 88 insertions(+), 102 deletions(-)

lib/std/Io.zig+39-11
...@@ -235,7 +235,6 @@ pub const VTable = struct {...@@ -235,7 +235,6 @@ pub const VTable = struct {
235 netListenUnix: *const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle,235 netListenUnix: *const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle,
236 netConnectUnix: *const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle,236 netConnectUnix: *const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle,
237 netSocketCreatePair: *const fn (?*anyopaque, net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket,237 netSocketCreatePair: *const fn (?*anyopaque, net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket,
238 netWrite: *const fn (?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize,
239 netWriteFile: *const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize,238 netWriteFile: *const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize,
240 netClose: *const fn (?*anyopaque, sockets: []const net.Socket) void,239 netClose: *const fn (?*anyopaque, sockets: []const net.Socket) void,
241 netShutdown: *const fn (?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void,240 netShutdown: *const fn (?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void,
...@@ -253,6 +252,7 @@ pub const Operation = union(enum) {...@@ -253,6 +252,7 @@ pub const Operation = union(enum) {
253 net_receive: NetReceive,252 net_receive: NetReceive,
254 net_send: NetSend,253 net_send: NetSend,
255 net_read: NetRead,254 net_read: NetRead,
255 net_write: NetWrite,
256256
257 pub const Tag = @typeInfo(Operation).@"union".tag_type.?;257 pub const Tag = @typeInfo(Operation).@"union".tag_type.?;
258258
...@@ -438,6 +438,43 @@ pub const Operation = union(enum) {...@@ -438,6 +438,43 @@ pub const Operation = union(enum) {
438 pub const Result = Error!usize;438 pub const Result = Error!usize;
439 };439 };
440440
441 pub const NetWrite = struct {
442 socket_handle: net.Socket.Handle,
443 header: []const u8 = &.{},
444 data: []const []const u8,
445 splat: usize = 1,
446
447 pub const Error = error{
448 /// Another TCP Fast Open is already in progress.
449 FastOpenAlreadyInProgress,
450 /// Network session was unexpectedly closed by recipient.
451 ConnectionResetByPeer,
452 /// The output queue for a network interface was full. This generally indicates that the
453 /// interface has stopped sending, but may be caused by transient congestion. (Normally,
454 /// this does not occur in Linux. Packets are just silently dropped when a device queue
455 /// overflows.)
456 ///
457 /// This is also caused when there is not enough kernel memory available.
458 SystemResources,
459 /// No route to network.
460 NetworkUnreachable,
461 /// Network reached but no route to host.
462 HostUnreachable,
463 /// The local network interface used to reach the destination is down.
464 NetworkDown,
465 /// The destination address is not listening.
466 ConnectionRefused,
467 /// The passed address didn't have the correct address family in its sa_family field.
468 AddressFamilyUnsupported,
469 /// Local end has been shut down on a connection-oriented socket, or
470 /// the socket was never connected.
471 SocketUnconnected,
472 SocketNotBound,
473 } || Io.UnexpectedError;
474
475 pub const Result = Error!usize;
476 };
477
441 pub const Result = Result: {478 pub const Result = Result: {
442 const operation_info = @typeInfo(Operation).@"union";479 const operation_info = @typeInfo(Operation).@"union";
443 const operation_count = operation_info.field_names.len;480 const operation_count = operation_info.field_names.len;
...@@ -2771,7 +2808,6 @@ pub const failing: std.Io = .{...@@ -2771,7 +2808,6 @@ pub const failing: std.Io = .{
2771 .netListenUnix = failingNetListenUnix,2808 .netListenUnix = failingNetListenUnix,
2772 .netConnectUnix = failingNetConnectUnix,2809 .netConnectUnix = failingNetConnectUnix,
2773 .netSocketCreatePair = failingNetSocketCreatePair,2810 .netSocketCreatePair = failingNetSocketCreatePair,
2774 .netWrite = failingNetWrite,
2775 .netWriteFile = failingNetWriteFile,2811 .netWriteFile = failingNetWriteFile,
2776 .netClose = unreachableNetClose,2812 .netClose = unreachableNetClose,
2777 .netShutdown = failingNetShutdown,2813 .netShutdown = failingNetShutdown,
...@@ -2920,6 +2956,7 @@ pub fn failingOperate(userdata: ?*anyopaque, operation: Operation) Cancelable!Op...@@ -2920,6 +2956,7 @@ pub fn failingOperate(userdata: ?*anyopaque, operation: Operation) Cancelable!Op
2920 .net_receive => .{ .net_receive = .{ error.NetworkDown, 0 } },2956 .net_receive => .{ .net_receive = .{ error.NetworkDown, 0 } },
2921 .net_send => .{ .net_send = .{ error.NetworkDown, 0 } },2957 .net_send => .{ .net_send = .{ error.NetworkDown, 0 } },
2922 .net_read => .{ .net_read = error.NetworkDown },2958 .net_read => .{ .net_read = error.NetworkDown },
2959 .net_write => .{ .net_write = error.NetworkDown },
2923 };2960 };
2924}2961}
29252962
...@@ -3515,15 +3552,6 @@ pub fn failingNetSocketCreatePair(userdata: ?*anyopaque, options: net.Socket.Cre...@@ -3515,15 +3552,6 @@ pub fn failingNetSocketCreatePair(userdata: ?*anyopaque, options: net.Socket.Cre
3515 return error.OperationUnsupported;3552 return error.OperationUnsupported;
3516}3553}
35173554
3518pub fn failingNetWrite(userdata: ?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize {
3519 _ = userdata;
3520 _ = dest;
3521 _ = header;
3522 _ = data;
3523 _ = splat;
3524 return error.NetworkDown;
3525}
3526
3527pub fn failingNetWriteFile(userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8, file_reader: *Io.File.Reader, limit: Io.Limit) net.Stream.Writer.WriteFileError!usize {3555pub fn failingNetWriteFile(userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8, file_reader: *Io.File.Reader, limit: Io.Limit) net.Stream.Writer.WriteFileError!usize {
3528 _ = userdata;3556 _ = userdata;
3529 _ = handle;3557 _ = handle;
lib/std/Io/Dispatch.zig+3-17
...@@ -458,7 +458,6 @@ pub fn io(ev: *Evented) Io {...@@ -458,7 +458,6 @@ pub fn io(ev: *Evented) Io {
458 .netListenUnix = netListenUnixUnavailable,458 .netListenUnix = netListenUnixUnavailable,
459 .netConnectUnix = netConnectUnixUnavailable,459 .netConnectUnix = netConnectUnixUnavailable,
460 .netSocketCreatePair = netSocketCreatePairUnavailable,460 .netSocketCreatePair = netSocketCreatePairUnavailable,
461 .netWrite = netWriteUnavailable,
462 .netWriteFile = netWriteFileUnavailable,461 .netWriteFile = netWriteFileUnavailable,
463 .netClose = netClose,462 .netClose = netClose,
464 .netShutdown = netShutdownUnavailable,463 .netShutdown = netShutdownUnavailable,
...@@ -1714,6 +1713,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper...@@ -1714,6 +1713,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper
1714 .net_receive => @panic("TODO implement net_receive operation"),1713 .net_receive => @panic("TODO implement net_receive operation"),
1715 .net_send => @panic("TODO implement net_send operation"),1714 .net_send => @panic("TODO implement net_send operation"),
1716 .net_read => @panic("TODO implement net_read operation"),1715 .net_read => @panic("TODO implement net_read operation"),
1716 .net_write => @panic("TODO implement net_write operation"),
1717 }1717 }
1718}1718}
17191719
...@@ -2136,6 +2136,7 @@ fn batchDrainSubmitted(...@@ -2136,6 +2136,7 @@ fn batchDrainSubmitted(
2136 .device_io_control => {},2136 .device_io_control => {},
2137 .net_receive => @panic("TODO implement batched net_receive"),2137 .net_receive => @panic("TODO implement batched net_receive"),
2138 .net_read => @panic("TODO implement batched net_read"),2138 .net_read => @panic("TODO implement batched net_read"),
2139 .net_write => @panic("TODO implement batched net_write"),
2139 };2140 };
2140 if (concurrency) return error.ConcurrencyUnavailable;2141 if (concurrency) return error.ConcurrencyUnavailable;
2141 break :result try operate(ev, storage.submission.operation);2142 break :result try operate(ev, storage.submission.operation);
...@@ -2196,6 +2197,7 @@ fn batchSourceEvent(context: ?*anyopaque) callconv(.c) void {...@@ -2196,6 +2197,7 @@ fn batchSourceEvent(context: ?*anyopaque) callconv(.c) void {
2196 .device_io_control => unreachable,2197 .device_io_control => unreachable,
2197 .net_receive => @panic("TODO implement batched net_receive"),2198 .net_receive => @panic("TODO implement batched net_receive"),
2198 .net_read => @panic("TODO implement batched net_read"),2199 .net_read => @panic("TODO implement batched net_read"),
2200 .net_write => @panic("TODO implement batched net_write"),
2199 };2201 };
22002202
2201 switch (pending.node.prev) {2203 switch (pending.node.prev) {
...@@ -4866,22 +4868,6 @@ fn netSocketCreatePairUnavailable(...@@ -4866,22 +4868,6 @@ fn netSocketCreatePairUnavailable(
4866 return error.OperationUnsupported;4868 return error.OperationUnsupported;
4867}4869}
48684870
4869fn netWriteUnavailable(
4870 userdata: ?*anyopaque,
4871 handle: net.Socket.Handle,
4872 header: []const u8,
4873 data: []const []const u8,
4874 splat: usize,
4875) net.Stream.Writer.Error!usize {
4876 const ev: *Evented = @ptrCast(@alignCast(userdata));
4877 _ = ev;
4878 _ = handle;
4879 _ = header;
4880 _ = data;
4881 _ = splat;
4882 return error.NetworkDown;
4883}
4884
4885fn netWriteFileUnavailable(4871fn netWriteFileUnavailable(
4886 userdata: ?*anyopaque,4872 userdata: ?*anyopaque,
4887 socket_handle: net.Socket.Handle,4873 socket_handle: net.Socket.Handle,
lib/std/Io/Kqueue.zig-19
...@@ -650,10 +650,8 @@ pub fn io(k: *Kqueue) Io {...@@ -650,10 +650,8 @@ pub fn io(k: *Kqueue) Io {
650 .netBindIp = netBindIp,650 .netBindIp = netBindIp,
651 .netConnectIp = netConnectIp,651 .netConnectIp = netConnectIp,
652 .netConnectUnix = netConnectUnix,652 .netConnectUnix = netConnectUnix,
653 .netClose = netClose,
654 .netShutdown = netShutdown,653 .netShutdown = netShutdown,
655 .netRead = netRead,654 .netRead = netRead,
656 .netWrite = netWrite,
657 .netSend = netSend,655 .netSend = netSend,
658 .netReceive = netReceive,656 .netReceive = netReceive,
659 .netInterfaceNameResolve = netInterfaceNameResolve,657 .netInterfaceNameResolve = netInterfaceNameResolve,
...@@ -1270,23 +1268,6 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea...@@ -1270,23 +1268,6 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea
1270 }1268 }
1271}1269}
12721270
1273fn netWrite(userdata: ?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize {
1274 const k: *Kqueue = @ptrCast(@alignCast(userdata));
1275 _ = k;
1276 _ = dest;
1277 _ = header;
1278 _ = data;
1279 _ = splat;
1280 @panic("TODO");
1281}
1282
1283fn netClose(userdata: ?*anyopaque, sockets: []const net.Socket) void {
1284 const k: *Kqueue = @ptrCast(@alignCast(userdata));
1285 _ = k;
1286 _ = sockets;
1287 @panic("TODO");
1288}
1289
1290fn netShutdown(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {1271fn netShutdown(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {
1291 const k: *Kqueue = @ptrCast(@alignCast(userdata));1272 const k: *Kqueue = @ptrCast(@alignCast(userdata));
1292 _ = k;1273 _ = k;
lib/std/Io/Threaded.zig+29-10
...@@ -1946,10 +1946,6 @@ pub fn io(t: *Threaded) Io {...@@ -1946,10 +1946,6 @@ pub fn io(t: *Threaded) Io {
1946 .windows => netShutdownWindows,1946 .windows => netShutdownWindows,
1947 else => netShutdownPosix,1947 else => netShutdownPosix,
1948 },1948 },
1949 .netWrite = switch (native_os) {
1950 .windows => netWriteWindows,
1951 else => netWritePosix,
1952 },
1953 .netWriteFile = netWriteFile,1949 .netWriteFile = netWriteFile,
1954 .netInterfaceNameResolve = netInterfaceNameResolve,1950 .netInterfaceNameResolve = netInterfaceNameResolve,
1955 .netInterfaceName = netInterfaceName,1951 .netInterfaceName = netInterfaceName,
...@@ -2586,6 +2582,15 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper...@@ -2586,6 +2582,15 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper
2586 else => |e| e,2582 else => |e| e,
2587 },2583 },
2588 },2584 },
2585 .net_write => |o| return .{
2586 .net_write = (if (is_windows)
2587 netWriteWindows(o.socket_handle, o.header, o.data, o.splat)
2588 else
2589 netWritePosix(o.socket_handle, o.header, o.data, o.splat)) catch |err| switch (err) {
2590 error.Canceled => |e| return e,
2591 else => |e| e,
2592 },
2593 },
2589 }2594 }
2590}2595}
25912596
...@@ -2657,6 +2662,14 @@ fn batchAwaitAsync(userdata: ?*anyopaque, b: *Io.Batch) Io.Cancelable!void {...@@ -2657,6 +2662,14 @@ fn batchAwaitAsync(userdata: ?*anyopaque, b: *Io.Batch) Io.Cancelable!void {
2657 };2662 };
2658 poll_len += 1;2663 poll_len += 1;
2659 },2664 },
2665 .net_write => |o| {
2666 poll_buffer[poll_len] = .{
2667 .fd = o.socket_handle,
2668 .events = posix.POLL.OUT | posix.POLL.ERR,
2669 .revents = 0,
2670 };
2671 poll_len += 1;
2672 },
2660 }2673 }
2661 index = submission.node.next;2674 index = submission.node.next;
2662 }2675 }
...@@ -2864,6 +2877,7 @@ fn batchAwaitConcurrent(userdata: ?*anyopaque, b: *Io.Batch, timeout: Io.Timeout...@@ -2864,6 +2877,7 @@ fn batchAwaitConcurrent(userdata: ?*anyopaque, b: *Io.Batch, timeout: Io.Timeout
2864 b.completed.tail = index;2877 b.completed.tail = index;
2865 },2878 },
2866 .net_read => |o| try poll_storage.add(o.socket_handle, posix.POLL.IN | posix.POLL.ERR),2879 .net_read => |o| try poll_storage.add(o.socket_handle, posix.POLL.IN | posix.POLL.ERR),
2880 .net_write => |o| try poll_storage.add(o.socket_handle, posix.POLL.OUT | posix.POLL.ERR),
2867 }2881 }
2868 index = submission.node.next;2882 index = submission.node.next;
2869 }2883 }
...@@ -3061,6 +3075,7 @@ fn batchApc(...@@ -3061,6 +3075,7 @@ fn batchApc(
3061 .net_receive => unreachable,3075 .net_receive => unreachable,
3062 .net_send => unreachable,3076 .net_send => unreachable,
3063 .net_read => unreachable,3077 .net_read => unreachable,
3078 .net_write => unreachable,
3064 };3079 };
3065 storage.* = .{ .completion = .{ .node = .{ .next = .none }, .result = result } };3080 storage.* = .{ .completion = .{ .node = .{ .next = .none }, .result = result } };
3066 },3081 },
...@@ -3286,6 +3301,16 @@ fn batchDrainSubmittedWindows(t: *Threaded, b: *Io.Batch, concurrency: bool) (Io...@@ -3286,6 +3301,16 @@ fn batchDrainSubmittedWindows(t: *Threaded, b: *Io.Batch, concurrency: bool) (Io
3286 },3301 },
3287 });3302 });
3288 },3303 },
3304 .net_write => |*o| {
3305 // TODO integrate with overlapped I/O or equivalent to avoid this error
3306 if (concurrency) return error.ConcurrencyUnavailable;
3307 batchCompleteBlockingWindows(b, operation_userdata, .{
3308 .net_write = netWriteWindows(o.socket_handle, o.header, o.data, o.splat) catch |err| switch (err) {
3309 error.Canceled => |e| return e,
3310 else => |e| e,
3311 },
3312 });
3313 },
3289 }3314 }
3290 index = submission.node.next;3315 index = submission.node.next;
3291 }3316 }
...@@ -13283,15 +13308,12 @@ fn netReceiveOneWindows(...@@ -13283,15 +13308,12 @@ fn netReceiveOneWindows(
13283}13308}
1328413309
13285fn netWritePosix(13310fn netWritePosix(
13286 userdata: ?*anyopaque,
13287 fd: net.Socket.Handle,13311 fd: net.Socket.Handle,
13288 header: []const u8,13312 header: []const u8,
13289 data: []const []const u8,13313 data: []const []const u8,
13290 splat: usize,13314 splat: usize,
13291) net.Stream.Writer.Error!usize {13315) net.Stream.Writer.Error!usize {
13292 if (!have_networking) return error.NetworkDown;13316 if (!have_networking) return error.NetworkDown;
13293 const t: *Threaded = @ptrCast(@alignCast(userdata));
13294 _ = t;
1329513317
13296 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;13318 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
13297 var msg: posix.msghdr_const = .{13319 var msg: posix.msghdr_const = .{
...@@ -13377,15 +13399,12 @@ fn netWritePosix(...@@ -13377,15 +13399,12 @@ fn netWritePosix(
13377}13399}
1337813400
13379fn netWriteWindows(13401fn netWriteWindows(
13380 userdata: ?*anyopaque,
13381 handle: net.Socket.Handle,13402 handle: net.Socket.Handle,
13382 header: []const u8,13403 header: []const u8,
13383 data: []const []const u8,13404 data: []const []const u8,
13384 splat: usize,13405 splat: usize,
13385) net.Stream.Writer.Error!usize {13406) net.Stream.Writer.Error!usize {
13386 if (!have_networking) return error.NetworkDown;13407 if (!have_networking) return error.NetworkDown;
13387 const t: *Threaded = @ptrCast(@alignCast(userdata));
13388 _ = t;
1338913408
13390 var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"const") = undefined;13409 var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"const") = undefined;
13391 var len: u32 = 0;13410 var len: u32 = 0;
lib/std/Io/Uring.zig+6-17
...@@ -778,7 +778,6 @@ pub fn io(ev: *Evented) Io {...@@ -778,7 +778,6 @@ pub fn io(ev: *Evented) Io {
778 .netListenUnix = netListenUnixUnavailable,778 .netListenUnix = netListenUnixUnavailable,
779 .netConnectUnix = netConnectUnixUnavailable,779 .netConnectUnix = netConnectUnixUnavailable,
780 .netSocketCreatePair = netSocketCreatePairUnavailable,780 .netSocketCreatePair = netSocketCreatePairUnavailable,
781 .netWrite = netWriteUnavailable,
782 .netWriteFile = netWriteFileUnavailable,781 .netWriteFile = netWriteFileUnavailable,
783 .netClose = netClose,782 .netClose = netClose,
784 .netShutdown = netShutdown,783 .netShutdown = netShutdown,
...@@ -2118,6 +2117,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper...@@ -2118,6 +2117,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper
2118 break :r error.NetworkDown; // TODO2117 break :r error.NetworkDown; // TODO
2119 },2118 },
2120 },2119 },
2120 .net_write => @panic("TODO implement net_write operation"),
2121 };2121 };
2122}2122}
21232123
...@@ -2413,6 +2413,10 @@ fn batchDrainSubmitted(...@@ -2413,6 +2413,10 @@ fn batchDrainSubmitted(
2413 _ = o;2413 _ = o;
2414 @panic("TODO implement batchDrainSubmitted for net_read");2414 @panic("TODO implement batchDrainSubmitted for net_read");
2415 },2415 },
2416 .net_write => |o| {
2417 _ = o;
2418 @panic("TODO implement batchDrainSubmitted for net_write");
2419 },
2416 })) |result| {2420 })) |result| {
2417 switch (batch.completed.tail) {2421 switch (batch.completed.tail) {
2418 .none => batch.completed.head = index,2422 .none => batch.completed.head = index,
...@@ -2516,6 +2520,7 @@ fn batchDrainReady(batch: *Io.Batch) Io.Timeout.Error!void {...@@ -2516,6 +2520,7 @@ fn batchDrainReady(batch: *Io.Batch) Io.Timeout.Error!void {
2516 .net_receive => @panic("TODO"),2520 .net_receive => @panic("TODO"),
2517 .net_send => @panic("TODO"),2521 .net_send => @panic("TODO"),
2518 .net_read => @panic("TODO"),2522 .net_read => @panic("TODO"),
2523 .net_write => @panic("TODO"),
2519 })) |result| {2524 })) |result| {
2520 switch (batch.completed.tail) {2525 switch (batch.completed.tail) {
2521 .none => batch.completed.head = index,2526 .none => batch.completed.head = index,
...@@ -5153,22 +5158,6 @@ fn netReceive(...@@ -5153,22 +5158,6 @@ fn netReceive(
5153 }5158 }
5154}5159}
51555160
5156fn netWriteUnavailable(
5157 userdata: ?*anyopaque,
5158 handle: net.Socket.Handle,
5159 header: []const u8,
5160 data: []const []const u8,
5161 splat: usize,
5162) net.Stream.Writer.Error!usize {
5163 const ev: *Evented = @ptrCast(@alignCast(userdata));
5164 _ = ev;
5165 _ = handle;
5166 _ = header;
5167 _ = data;
5168 _ = splat;
5169 return error.NetworkDown;
5170}
5171
5172fn netWriteFileUnavailable(5161fn netWriteFileUnavailable(
5173 userdata: ?*anyopaque,5162 userdata: ?*anyopaque,
5174 socket_handle: net.Socket.Handle,5163 socket_handle: net.Socket.Handle,
lib/std/Io/net.zig+11-28
...@@ -1348,33 +1348,7 @@ pub const Stream = struct {...@@ -1348,33 +1348,7 @@ pub const Stream = struct {
1348 err: ?Error = null,1348 err: ?Error = null,
1349 write_file_err: ?WriteFileError = null,1349 write_file_err: ?WriteFileError = null,
13501350
1351 pub const Error = error{1351 pub const Error = Io.Operation.NetWrite.Error || Io.Cancelable;
1352 /// Another TCP Fast Open is already in progress.
1353 FastOpenAlreadyInProgress,
1354 /// Network session was unexpectedly closed by recipient.
1355 ConnectionResetByPeer,
1356 /// The output queue for a network interface was full. This generally indicates that the
1357 /// interface has stopped sending, but may be caused by transient congestion. (Normally,
1358 /// this does not occur in Linux. Packets are just silently dropped when a device queue
1359 /// overflows.)
1360 ///
1361 /// This is also caused when there is not enough kernel memory available.
1362 SystemResources,
1363 /// No route to network.
1364 NetworkUnreachable,
1365 /// Network reached but no route to host.
1366 HostUnreachable,
1367 /// The local network interface used to reach the destination is down.
1368 NetworkDown,
1369 /// The destination address is not listening.
1370 ConnectionRefused,
1371 /// The passed address didn't have the correct address family in its sa_family field.
1372 AddressFamilyUnsupported,
1373 /// Local end has been shut down on a connection-oriented socket, or
1374 /// the socket was never connected.
1375 SocketUnconnected,
1376 SocketNotBound,
1377 } || Io.UnexpectedError || Io.Cancelable;
13781352
1379 pub const WriteFileError = Error || error{1353 pub const WriteFileError = Error || error{
1380 /// The `Io` implementation cannot offer a more efficient1354 /// The `Io` implementation cannot offer a more efficient
...@@ -1407,7 +1381,16 @@ pub const Stream = struct {...@@ -1407,7 +1381,16 @@ pub const Stream = struct {
1407 const io = w.io;1381 const io = w.io;
1408 const buffered = io_w.buffered();1382 const buffered = io_w.buffered();
1409 const handle = w.stream.socket.handle;1383 const handle = w.stream.socket.handle;
1410 const n = io.vtable.netWrite(io.userdata, handle, buffered, data, splat) catch |err| {1384 const result = io.operate(.{ .net_write = .{
1385 .socket_handle = handle,
1386 .header = buffered,
1387 .data = data,
1388 .splat = splat,
1389 } }) catch |err| {
1390 w.err = err;
1391 return error.WriteFailed;
1392 };
1393 const n = result.net_write catch |err| {
1411 w.err = err;1394 w.err = err;
1412 return error.WriteFailed;1395 return error.WriteFailed;
1413 };1396 };