| author | |
| committer | |
| log | 9d92d2ce93c52083fe405716a6cf05151384b76e |
| tree | 13c48aa35738f4604330037d64ec4f66c4adad06 |
| parent | 254c23b03875387798b8ce779223091c5f6ee444 |
Preparation for adding timeouts:
https://codeberg.org/ziglang/zig/issues/321666 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, | ||
| 256 | 256 | ||
| 257 | pub const Tag = @typeInfo(Operation).@"union".tag_type.?; | 257 | pub const Tag = @typeInfo(Operation).@"union".tag_type.?; |
| 258 | 258 | ||
| ... | @@ -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 | }; |
| 440 | 440 | ||
| 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 | } |
| 2925 | 2962 | ||
| ... | @@ -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 | } |
| 3517 | 3554 | ||
| 3518 | pub 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 | |||
| 3527 | pub fn failingNetWriteFile(userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8, file_reader: *Io.File.Reader, limit: Io.Limit) net.Stream.Writer.WriteFileError!usize { | 3555 | pub 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 | } |
| 1719 | 1719 | ||
| ... | @@ -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 | }; |
| 2200 | 2202 | ||
| 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 | } |
| 4868 | 4870 | ||
| 4869 | fn 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 | |||
| 4885 | fn netWriteFileUnavailable( | 4871 | fn 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 | } |
| 1272 | 1270 | ||
| 1273 | fn 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 | |||
| 1283 | fn netClose(userdata: ?*anyopaque, sockets: []const net.Socket) void { | ||
| 1284 | const k: *Kqueue = @ptrCast(@alignCast(userdata)); | ||
| 1285 | _ = k; | ||
| 1286 | _ = sockets; | ||
| 1287 | @panic("TODO"); | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | fn netShutdown(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void { | 1271 | fn 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 | } |
| 2591 | 2596 | ||
| ... | @@ -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 | } |
| 13284 | 13309 | ||
| 13285 | fn netWritePosix( | 13310 | fn 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; | ||
| 13295 | 13317 | ||
| 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 | } |
| 13378 | 13400 | ||
| 13379 | fn netWriteWindows( | 13401 | fn 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; | ||
| 13389 | 13408 | ||
| 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; // TODO | 2117 | break :r error.NetworkDown; // TODO |
| 2119 | }, | 2118 | }, |
| 2120 | }, | 2119 | }, |
| 2120 | .net_write => @panic("TODO implement net_write operation"), | ||
| 2121 | }; | 2121 | }; |
| 2122 | } | 2122 | } |
| 2123 | 2123 | ||
| ... | @@ -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 | } |
| 5155 | 5160 | ||
| 5156 | fn 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 | |||
| 5172 | fn netWriteFileUnavailable( | 5161 | fn 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, |
| 1350 | 1350 | ||
| 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; | ||
| 1378 | 1352 | ||
| 1379 | pub const WriteFileError = Error || error{ | 1353 | pub const WriteFileError = Error || error{ |
| 1380 | /// The `Io` implementation cannot offer a more efficient | 1354 | /// 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 | }; |