diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-27 20:51:09 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | a458b6e610ed573b987ade7c0048663e57fb7191 (patch) | |
| tree | 8afecb4478b3d9d76df55aa67d6183785fcdc5e6 /src/ninep/ctl.zig | |
| parent | c3e2cd3b854964ca7db3798cb8750ee6d0833057 (diff) | |
| download | pardes-a458b6e610ed573b987ade7c0048663e57fb7191.tar.gz pardes-a458b6e610ed573b987ade7c0048663e57fb7191.zip | |
Answer a held read by its cloud9 ticket, refuse a second, and say a pane shut down
The held read is now kept by the Ticket cloud9's Conn.hold() gives its
park and answered through Conn.answerWith(), which makes the answer only
while that very park still waits, instead of walking the engine's slots
by tag; pardes no longer reaches into the engine for it. A second read on
an open whose read is held fails with file in use rather than sitting
parked where nothing answers it, and a read that waits with no open
record to hold it is logged and asserted on. A read on an event or
pty/data open whose pane closed answers acme's "window shut down"
(editors/acme/xfid.c:1005). The pane keeps its run's and its lock's open
handles, checked through openOf on use, not record indices. Docs: lock
from a shell needs a held fd, and a command that clears the screen may
read as cut.
Needs cloud9 zvuqvnzy (cca47d63), which adds Conn.hold, waiting and
answerWith; build.zig.zon still pins 82d8152c until that is pushed and
re-pinned.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
| -rw-r--r-- | src/ninep/ctl.zig | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 83b1196f..a3c1ab9e 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -192,9 +192,15 @@ pub fn readPane(p: *Pardes, req: Req, pane: *Pane) Reply { /// the keyboard. It belongs to the open that wrote it, which alone may /// `unlock`, and closing that open or the pane gives it up. pub fn writePane(p: *Pardes, req: Req, pane: *Pane) Reply { - // The record of this open is what holds the lock; a write that came on - // no writable open (the editor's own) has none. - const mine: ?u8 = if (tree.openOf(p, req)) |o| @intCast(o - &p.fs.opens[0]) else null; + // This open's handle is what holds the lock; a write that came on no + // writable open (the editor's own) has none. + const mine: ?u32 = if (tree.openOf(p, req)) |o| (if (o.what == .ctl) req.handle else null) else null; + // The pane keeps the holder's handle, which names that open only on + // this pane's ctl node; one that no longer does holds nothing. + if (pane.fs.lock) |h| { + const o = tree.openOf(p, .{ .tag = 0, .op = .write, .node = tree.Node.of(pane.serial, .ctl), .handle = h }); + if (o == null or o.?.what != .ctl) pane.fs.lock = null; + } const other = pane.fs.lock != null and pane.fs.lock != mine; var asked = false; // Checked whole before anything applies, so a write that must wait for @@ -337,7 +343,7 @@ test "a second lock waits until the holder unlocks or closes, and binds nobody e try testing.expect(pardes.turn.parked); try testing.expectEqual(Status.ok, w.ctl(p, ctl_node, a, "lock\nunlock\nlock\n").reply.status); try testing.expectEqual(E.INVAL, w.ctl(p, ctl_node, a, "unlock\nunlock\n").errno()); - try testing.expectEqual(@as(?u8, @intCast(a - 1)), p.panes[0].?.fs.lock); + try testing.expectEqual(@as(?u32, a), p.panes[0].?.fs.lock); // The lock lives and dies with the pane: closing it wakes whoever waits. const other = try th.newPane(p); |
