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(
233233 if (result) |stream| {
234234 return stream;
235235 } else |err| switch (err) {
236 error.Canceled => unreachable,
237
236238 error.SystemResources,
237239 error.OptionUnsupported,
238240 error.ProcessFdQuotaExceeded,
239241 error.SystemFdQuotaExceeded,
240 error.Canceled,
241242 => |e| return e,
242243
243244 error.WouldBlock => return error.Unexpected,
......@@ -259,6 +260,8 @@ pub fn connect(
259260/// Asynchronously establishes a connection to all IP addresses associated with
260261/// a host name, adding them to a results queue upon completion.
261262///
263/// `error.Canceled` will never be added to the queue, but other errors may be.
264///
262265/// Closes `results` before return, even on error.
263266///
264267/// Asserts `results` is not closed until this call returns.
......@@ -299,22 +302,15 @@ fn enqueueConnection(
299302 io: Io,
300303 queue: *Io.Queue(IpAddress.ConnectError!Stream),
301304 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,
312305) 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 };
314310 errdefer if (result) |s| s.close(io) else |_| {};
315311 queue.putOne(io, result) catch |err| switch (err) {
316 error.Closed => unreachable, // `queue` must not be closed
317312 error.Canceled => |e| return e,
313 error.Closed => unreachable, // `queue` must not be closed
318314 };
319315}
320316