authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-12-31 13:11:05+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-01-03 15:45:11+00:00
log3bb2f7b84ed8b1ee09b6077f66e28ab7291a7bd4
tree3b9f2500ab2e3c027eec8e87f62dd3d610bdf6d8
parentf306a9f84a006a6429f485a6c99ac26723f1e1e4
signaturelock-open Commit is signed but in an unrecognized format.

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).

1 files changed, 9 insertions(+), 13 deletions(-)

lib/std/Io/net/HostName.zig+9-13
...@@ -233,11 +233,12 @@ pub fn connect(...@@ -233,11 +233,12 @@ pub fn connect(
233 if (result) |stream| {233 if (result) |stream| {
234 return stream;234 return stream;
235 } else |err| switch (err) {235 } else |err| switch (err) {
236 error.Canceled => unreachable,
237
236 error.SystemResources,238 error.SystemResources,
237 error.OptionUnsupported,239 error.OptionUnsupported,
238 error.ProcessFdQuotaExceeded,240 error.ProcessFdQuotaExceeded,
239 error.SystemFdQuotaExceeded,241 error.SystemFdQuotaExceeded,
240 error.Canceled,
241 => |e| return e,242 => |e| return e,
242243
243 error.WouldBlock => return error.Unexpected,244 error.WouldBlock => return error.Unexpected,
...@@ -259,6 +260,8 @@ pub fn connect(...@@ -259,6 +260,8 @@ pub fn connect(
259/// Asynchronously establishes a connection to all IP addresses associated with260/// Asynchronously establishes a connection to all IP addresses associated with
260/// a host name, adding them to a results queue upon completion.261/// a host name, adding them to a results queue upon completion.
261///262///
263/// `error.Canceled` will never be added to the queue, but other errors may be.
264///
262/// Closes `results` before return, even on error.265/// Closes `results` before return, even on error.
263///266///
264/// Asserts `results` is not closed until this call returns.267/// Asserts `results` is not closed until this call returns.
...@@ -299,22 +302,15 @@ fn enqueueConnection(...@@ -299,22 +302,15 @@ fn enqueueConnection(
299 io: Io,302 io: Io,
300 queue: *Io.Queue(IpAddress.ConnectError!Stream),303 queue: *Io.Queue(IpAddress.ConnectError!Stream),
301 options: IpAddress.ConnectOptions,304 options: IpAddress.ConnectOptions,
302) void {
303 enqueueConnectionFallible(address, io, queue, options) catch |err| switch (err) {
304 error.Canceled => {},
305 };
306}
307fn enqueueConnectionFallible(
308 address: IpAddress,
309 io: Io,
310 queue: *Io.Queue(IpAddress.ConnectError!Stream),
311 options: IpAddress.ConnectOptions,
312) Io.Cancelable!void {305) Io.Cancelable!void {
313 const result = address.connect(io, options);306 const result = address.connect(io, options) catch |err| switch (err) {
307 error.Canceled => |e| return e,
308 else => |e| e, // other errors go in the result queue
309 };
314 errdefer if (result) |s| s.close(io) else |_| {};310 errdefer if (result) |s| s.close(io) else |_| {};
315 queue.putOne(io, result) catch |err| switch (err) {311 queue.putOne(io, result) catch |err| switch (err) {
316 error.Closed => unreachable, // `queue` must not be closed
317 error.Canceled => |e| return e,312 error.Canceled => |e| return e,
313 error.Closed => unreachable, // `queue` must not be closed
318 };314 };
319}315}
320316