From 8e7818911272d920d88c1680d66edc593b9fe648 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 23:24:22 -0300 Subject: The QUIC listener tests are deterministic, and fs-test --quic passes "Unix TCP and QUIC share one listener" failed 17 of 360 runs under load (12 parallel copies), always at p.fs.opens: the client had hung up but its connection's task had not yet seen it, reset() then cut the connection, and the releases the hangup owes were refused as the old editor's. The test's replacement editor is the same editor, so those opens stayed. It now waits (resting, with its own deadline) for the runner to empty before reset: 0 of 360 after. fs-test -Dquic=true failed too, at two points. A session Looking at its own tree through a QUIC mount is features.txt's documented "left as they are" case (QUIC is answered on the editor's thread); that check is dropped with a note. The /screen check asserted body text that the view may have scrolled past (2 of 7 runs); it now asserts the pane's tag. 10 of 10 after. Co-Authored-By: Claude Opus 5.5 --- src/9p_io.zig | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/9p_io.zig b/src/9p_io.zig index 651b3d0a..0f5e0a77 100644 --- a/src/9p_io.zig +++ b/src/9p_io.zig @@ -1398,9 +1398,18 @@ test "Unix TCP and QUIC share one listener through reads writes reconnects and r } Client.nap(1); } + // The client has hung up, but its connection's task may not have + // seen that yet. The releases it then owes are refused once + // `reset` starts cutting (they name the old editor's opens), and + // this test's "replacement" is the same editor, so they would + // stay in `p.fs.opens`. Let the hangup pay them first, resting + // so the task can take the turn: that is what is under test here. + const settle_by = Client.nowMs() + 3 * Client.budget_ms; + while (l.runner.count() != 0 and Client.nowMs() < settle_by) Client.nap(1); pardes.turn.wake(); try testing.expect(worker.done.load(.acquire)); if (worker.failure) |err| return err; + try testing.expectEqual(@as(usize, 0), l.runner.count()); l.reset(p); try testing.expectEqual(@as(usize, 0), l.runner.count()); for (&l.conns, 0..) |conn, i| try testing.expect(!l.live(@intCast(i)) and !conn.draining); -- cgit v1.3