diff options
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); |
