diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 17:53:02 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | 031989d927b07d38f0874a0b78a52f54ad285efb (patch) | |
| tree | 1172d6d1afc72b03f4768030443a17cd2a6dc22d /src/ninep | |
| parent | e3e605bd33fc5be56cb7ec842449718bc5337a75 (diff) | |
| download | pardes-031989d927b07d38f0874a0b78a52f54ad285efb.tar.gz pardes-031989d927b07d38f0874a0b78a52f54ad285efb.zip | |
Writes held before the shell's clock is first seen no longer overflow its first step
A 9P write served before a detached host's first pump holds its batch stamped at time 0, so nextWake said to wake at 20 ms while advance, seeing the clock for the first time, set stepped_ns days later and counted due - stepped_ns back past zero: an integer-overflow panic. It was what the 64 KiB msize trial hit in fs-test (restore detached space, the connection closing at the first write's clunk), a race any msize can lose. A batch's wake is now never before the next frame.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep')
| -rw-r--r-- | src/ninep/pane.zig | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig index 4327c403..bb4ebf86 100644 --- a/src/ninep/pane.zig +++ b/src/ninep/pane.zig @@ -1190,6 +1190,21 @@ test "an open's writes in a row are held and go in as one edit, seen by the next try testing.expectEqualStrings("abone\n", rd(p, body, 0, 64).bytes); } +test "writes held before the shell's clock is first seen go in at its first step" { + const p = try withFile(testing.allocator, "one\n"); + defer p.deinit(); + const body = Node.of(serialOf(p), .body); + try testing.expect(!p.clock_started); + const h = call(p, .{ .tag = 1, .op = .open, .node = body, .omode = 1 }).reply.handle; + const revision = p.panes[0].?.file.?.revision; + _ = call(p, .{ .tag = 2, .op = .write, .node = body, .handle = h, .data = "x\n" }); + try testing.expectEqual(@as(u64, 0), p.fs.batch.last_ns); + // A detached host's first step: its clock is days into the machine's. + p.advance(700_000 * std.time.ns_per_s); + flushPausedBatch(p); + try testing.expectEqual(revision + 1, p.panes[0].?.file.?.revision); +} + test "a tag write past the limit is refused whole, naming the limit" { const p = try withFile(testing.allocator, "x\n"); defer p.deinit(); |
