| 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 | 235 | netListenUnix: *const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle, |
| 236 | 236 | netConnectUnix: *const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle, |
| 237 | 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 | 238 | netWriteFile: *const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize, |
| 240 | 239 | netClose: *const fn (?*anyopaque, sockets: []const net.Socket) void, |
| 241 | 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 | 252 | net_receive: NetReceive, |
| 254 | 253 | net_send: NetSend, |
| 255 | 254 | net_read: NetRead, |
| 255 | net_write: NetWrite, | |
| 256 | 256 | |
| 257 | 257 | pub const Tag = @typeInfo(Operation).@"union".tag_type.?; |
| 258 | 258 | |
| ... | ... | @@ -438,6 +438,43 @@ pub const Operation = union(enum) { |
| 438 | 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 | 478 | pub const Result = Result: { |
| 442 | 479 | const operation_info = @typeInfo(Operation).@"union"; |
| 443 | 480 | const operation_count = operation_info.field_names.len; |
| ... | ... | @@ -2771,7 +2808,6 @@ pub const failing: std.Io = .{ |
| 2771 | 2808 | .netListenUnix = failingNetListenUnix, |
| 2772 | 2809 | .netConnectUnix = failingNetConnectUnix, |
| 2773 | 2810 | .netSocketCreatePair = failingNetSocketCreatePair, |
| 2774 | .netWrite = failingNetWrite, | |
| 2775 | 2811 | .netWriteFile = failingNetWriteFile, |
| 2776 | 2812 | .netClose = unreachableNetClose, |
| 2777 | 2813 | .netShutdown = failingNetShutdown, |
| ... | ... | @@ -2920,6 +2956,7 @@ pub fn failingOperate(userdata: ?*anyopaque, operation: Operation) Cancelable!Op |
| 2920 | 2956 | .net_receive => .{ .net_receive = .{ error.NetworkDown, 0 } }, |
| 2921 | 2957 | .net_send => .{ .net_send = .{ error.NetworkDown, 0 } }, |
| 2922 | 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 | 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 | 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 | 3556 | _ = userdata; |
| 3529 | 3557 | _ = handle; |
lib/std/Io/Dispatch.zig+3-17| ... | ... | @@ -458,7 +458,6 @@ pub fn io(ev: *Evented) Io { |
| 458 | 458 | .netListenUnix = netListenUnixUnavailable, |
| 459 | 459 | .netConnectUnix = netConnectUnixUnavailable, |
| 460 | 460 | .netSocketCreatePair = netSocketCreatePairUnavailable, |
| 461 | .netWrite = netWriteUnavailable, | |
| 462 | 461 | .netWriteFile = netWriteFileUnavailable, |
| 463 | 462 | .netClose = netClose, |
| 464 | 463 | .netShutdown = netShutdownUnavailable, |
| ... | ... | @@ -1714,6 +1713,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper |
| 1714 | 1713 | .net_receive => @panic("TODO implement net_receive operation"), |
| 1715 | 1714 | .net_send => @panic("TODO implement net_send operation"), |
| 1716 | 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 | 2136 | .device_io_control => {}, |
| 2137 | 2137 | .net_receive => @panic("TODO implement batched net_receive"), |
| 2138 | 2138 | .net_read => @panic("TODO implement batched net_read"), |
| 2139 | .net_write => @panic("TODO implement batched net_write"), | |
| 2139 | 2140 | }; |
| 2140 | 2141 | if (concurrency) return error.ConcurrencyUnavailable; |
| 2141 | 2142 | break :result try operate(ev, storage.submission.operation); |
| ... | ... | @@ -2196,6 +2197,7 @@ fn batchSourceEvent(context: ?*anyopaque) callconv(.c) void { |
| 2196 | 2197 | .device_io_control => unreachable, |
| 2197 | 2198 | .net_receive => @panic("TODO implement batched net_receive"), |
| 2198 | 2199 | .net_read => @panic("TODO implement batched net_read"), |
| 2200 | .net_write => @panic("TODO implement batched net_write"), | |
| 2199 | 2201 | }; |
| 2200 | 2202 | |
| 2201 | 2203 | switch (pending.node.prev) { |
| ... | ... | @@ -4866,22 +4868,6 @@ fn netSocketCreatePairUnavailable( |
| 4866 | 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 | 4871 | fn netWriteFileUnavailable( |
| 4886 | 4872 | userdata: ?*anyopaque, |
| 4887 | 4873 | socket_handle: net.Socket.Handle, |
lib/std/Io/Kqueue.zig-19| ... | ... | @@ -650,10 +650,8 @@ pub fn io(k: *Kqueue) Io { |
| 650 | 650 | .netBindIp = netBindIp, |
| 651 | 651 | .netConnectIp = netConnectIp, |
| 652 | 652 | .netConnectUnix = netConnectUnix, |
| 653 | .netClose = netClose, | |
| 654 | 653 | .netShutdown = netShutdown, |
| 655 | 654 | .netRead = netRead, |
| 656 | .netWrite = netWrite, | |
| 657 | 655 | .netSend = netSend, |
| 658 | 656 | .netReceive = netReceive, |
| 659 | 657 | .netInterfaceNameResolve = netInterfaceNameResolve, |
| ... | ... | @@ -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 | 1271 | fn netShutdown(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void { |
| 1291 | 1272 | const k: *Kqueue = @ptrCast(@alignCast(userdata)); |
| 1292 | 1273 | _ = k; |
lib/std/Io/Threaded.zig+29-10| ... | ... | @@ -1946,10 +1946,6 @@ pub fn io(t: *Threaded) Io { |
| 1946 | 1946 | .windows => netShutdownWindows, |
| 1947 | 1947 | else => netShutdownPosix, |
| 1948 | 1948 | }, |
| 1949 | .netWrite = switch (native_os) { | |
| 1950 | .windows => netWriteWindows, | |
| 1951 | else => netWritePosix, | |
| 1952 | }, | |
| 1953 | 1949 | .netWriteFile = netWriteFile, |
| 1954 | 1950 | .netInterfaceNameResolve = netInterfaceNameResolve, |
| 1955 | 1951 | .netInterfaceName = netInterfaceName, |
| ... | ... | @@ -2586,6 +2582,15 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper |
| 2586 | 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 | 2662 | }; |
| 2658 | 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 | 2674 | index = submission.node.next; |
| 2662 | 2675 | } |
| ... | ... | @@ -2864,6 +2877,7 @@ fn batchAwaitConcurrent(userdata: ?*anyopaque, b: *Io.Batch, timeout: Io.Timeout |
| 2864 | 2877 | b.completed.tail = index; |
| 2865 | 2878 | }, |
| 2866 | 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 | 2882 | index = submission.node.next; |
| 2869 | 2883 | } |
| ... | ... | @@ -3061,6 +3075,7 @@ fn batchApc( |
| 3061 | 3075 | .net_receive => unreachable, |
| 3062 | 3076 | .net_send => unreachable, |
| 3063 | 3077 | .net_read => unreachable, |
| 3078 | .net_write => unreachable, | |
| 3064 | 3079 | }; |
| 3065 | 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 | 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 | 3315 | index = submission.node.next; |
| 3291 | 3316 | } |
| ... | ... | @@ -13283,15 +13308,12 @@ fn netReceiveOneWindows( |
| 13283 | 13308 | } |
| 13284 | 13309 | |
| 13285 | 13310 | fn netWritePosix( |
| 13286 | userdata: ?*anyopaque, | |
| 13287 | 13311 | fd: net.Socket.Handle, |
| 13288 | 13312 | header: []const u8, |
| 13289 | 13313 | data: []const []const u8, |
| 13290 | 13314 | splat: usize, |
| 13291 | 13315 | ) net.Stream.Writer.Error!usize { |
| 13292 | 13316 | if (!have_networking) return error.NetworkDown; |
| 13293 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | |
| 13294 | _ = t; | |
| 13295 | 13317 | |
| 13296 | 13318 | var iovecs: [max_iovecs_len]posix.iovec_const = undefined; |
| 13297 | 13319 | var msg: posix.msghdr_const = .{ |
| ... | ... | @@ -13377,15 +13399,12 @@ fn netWritePosix( |
| 13377 | 13399 | } |
| 13378 | 13400 | |
| 13379 | 13401 | fn netWriteWindows( |
| 13380 | userdata: ?*anyopaque, | |
| 13381 | 13402 | handle: net.Socket.Handle, |
| 13382 | 13403 | header: []const u8, |
| 13383 | 13404 | data: []const []const u8, |
| 13384 | 13405 | splat: usize, |
| 13385 | 13406 | ) net.Stream.Writer.Error!usize { |
| 13386 | 13407 | if (!have_networking) return error.NetworkDown; |
| 13387 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | |
| 13388 | _ = t; | |
| 13389 | 13408 | |
| 13390 | 13409 | var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"const") = undefined; |
| 13391 | 13410 | var len: u32 = 0; |
lib/std/Io/Uring.zig+6-17| ... | ... | @@ -778,7 +778,6 @@ pub fn io(ev: *Evented) Io { |
| 778 | 778 | .netListenUnix = netListenUnixUnavailable, |
| 779 | 779 | .netConnectUnix = netConnectUnixUnavailable, |
| 780 | 780 | .netSocketCreatePair = netSocketCreatePairUnavailable, |
| 781 | .netWrite = netWriteUnavailable, | |
| 782 | 781 | .netWriteFile = netWriteFileUnavailable, |
| 783 | 782 | .netClose = netClose, |
| 784 | 783 | .netShutdown = netShutdown, |
| ... | ... | @@ -2118,6 +2117,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper |
| 2118 | 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 | 2413 | _ = o; |
| 2414 | 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 | 2420 | })) |result| { |
| 2417 | 2421 | switch (batch.completed.tail) { |
| 2418 | 2422 | .none => batch.completed.head = index, |
| ... | ... | @@ -2516,6 +2520,7 @@ fn batchDrainReady(batch: *Io.Batch) Io.Timeout.Error!void { |
| 2516 | 2520 | .net_receive => @panic("TODO"), |
| 2517 | 2521 | .net_send => @panic("TODO"), |
| 2518 | 2522 | .net_read => @panic("TODO"), |
| 2523 | .net_write => @panic("TODO"), | |
| 2519 | 2524 | })) |result| { |
| 2520 | 2525 | switch (batch.completed.tail) { |
| 2521 | 2526 | .none => batch.completed.head = index, |
| ... | ... | @@ -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 | 5161 | fn netWriteFileUnavailable( |
| 5173 | 5162 | userdata: ?*anyopaque, |
| 5174 | 5163 | socket_handle: net.Socket.Handle, |
lib/std/Io/net.zig+11-28| ... | ... | @@ -1348,33 +1348,7 @@ pub const Stream = struct { |
| 1348 | 1348 | err: ?Error = null, |
| 1349 | 1349 | write_file_err: ?WriteFileError = null, |
| 1350 | 1350 | |
| 1351 | pub const Error = error{ | |
| 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; | |
| 1351 | pub const Error = Io.Operation.NetWrite.Error || Io.Cancelable; | |
| 1378 | 1352 | |
| 1379 | 1353 | pub const WriteFileError = Error || error{ |
| 1380 | 1354 | /// The `Io` implementation cannot offer a more efficient |
| ... | ... | @@ -1407,7 +1381,16 @@ pub const Stream = struct { |
| 1407 | 1381 | const io = w.io; |
| 1408 | 1382 | const buffered = io_w.buffered(); |
| 1409 | 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 | 1394 | w.err = err; |
| 1412 | 1395 | return error.WriteFailed; |
| 1413 | 1396 | }; |