commit 3bb2f7b84ed8b1ee09b6077f66e28ab7291a7bd4 (tree)
parent f306a9f84a006a6429f485a6c99ac26723f1e1e4
Author: Matthew Lugg <mlugg@mlugg.co.uk>
Date: Wed, 31 Dec 2025 13:11:05 +0000
std.Io.net: don't swallow 'error.Canceled'
This was missed when updating to the new group cancelation API, and
caused illegal behavior in many cases (the condition was simply that a
DNS query returned a second result before a connection was successfully
established).
Diffstat:
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/lib/std/Io/net/HostName.zig b/lib/std/Io/net/HostName.zig
@@ -233,11 +233,12 @@ pub fn connect(
if (result) |stream| {
return stream;
} else |err| switch (err) {
+ error.Canceled => unreachable,
+
error.SystemResources,
error.OptionUnsupported,
error.ProcessFdQuotaExceeded,
error.SystemFdQuotaExceeded,
- error.Canceled,
=> |e| return e,
error.WouldBlock => return error.Unexpected,
@@ -259,6 +260,8 @@ pub fn connect(
/// Asynchronously establishes a connection to all IP addresses associated with
/// a host name, adding them to a results queue upon completion.
///
+/// `error.Canceled` will never be added to the queue, but other errors may be.
+///
/// Closes `results` before return, even on error.
///
/// Asserts `results` is not closed until this call returns.
@@ -299,22 +302,15 @@ fn enqueueConnection(
io: Io,
queue: *Io.Queue(IpAddress.ConnectError!Stream),
options: IpAddress.ConnectOptions,
-) void {
- enqueueConnectionFallible(address, io, queue, options) catch |err| switch (err) {
- error.Canceled => {},
- };
-}
-fn enqueueConnectionFallible(
- address: IpAddress,
- io: Io,
- queue: *Io.Queue(IpAddress.ConnectError!Stream),
- options: IpAddress.ConnectOptions,
) Io.Cancelable!void {
- const result = address.connect(io, options);
+ const result = address.connect(io, options) catch |err| switch (err) {
+ error.Canceled => |e| return e,
+ else => |e| e, // other errors go in the result queue
+ };
errdefer if (result) |s| s.close(io) else |_| {};
queue.putOne(io, result) catch |err| switch (err) {
- error.Closed => unreachable, // `queue` must not be closed
error.Canceled => |e| return e,
+ error.Closed => unreachable, // `queue` must not be closed
};
}