summaryrefslogtreecommitdiff
path: root/src/ninep/events.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/events.zig')
-rw-r--r--src/ninep/events.zig49
1 files changed, 23 insertions, 26 deletions
diff --git a/src/ninep/events.zig b/src/ninep/events.zig
index 6b8c744e..78945c5c 100644
--- a/src/ninep/events.zig
+++ b/src/ninep/events.zig
@@ -115,19 +115,14 @@ pub fn readQueue(p: *Pardes, req: Req, q: *Queue) Reply {
pub const LogKind = enum { new, del, rename, save };
-/// A pane installed now is announced by `announce` once the update that made
-/// it has finished, when its name is known.
-pub fn noteInstall(p: *Pardes, id: usize) void {
- if (id < MAX_PANES) p.fs.panes[id].unannounced = true;
-}
-
-/// A pane leaving; one never announced leaves silently.
-pub fn noteRetire(p: *Pardes, id: usize, pane: *Pane) void {
- if (id >= MAX_PANES) return;
- tree.pty.shellGone(p, id);
+/// A pane leaving, before its state goes with it; one never announced
+/// leaves silently.
+pub fn noteRetire(p: *Pardes, pane: *Pane) void {
+ tree.pty.shellGone(p, pane);
p.fs.news = true; // a read held on its event or pty/data hears it went
- if (p.fs.panes[id].unannounced) {
- p.fs.panes[id].unannounced = false;
+ p.fs.listeners -|= pane.fs.readers;
+ if (pane.fs.unannounced) {
+ pane.fs.unannounced = false;
return;
}
noteLog(p, .del, pane);
@@ -135,11 +130,11 @@ pub fn noteRetire(p: *Pardes, id: usize, pane: *Pane) void {
/// Called at the end of every update: reports the panes installed by it.
pub fn announce(p: *Pardes) void {
- for (p.panes, 0..) |slot, id| {
- const pf = &p.fs.panes[id];
- if (!pf.unannounced) continue;
- pf.unannounced = false;
- if (slot) |pane| noteLog(p, .new, pane);
+ for (p.panes) |slot| {
+ const pane = slot orelse continue;
+ if (!pane.fs.unannounced) continue;
+ pane.fs.unannounced = false;
+ noteLog(p, .new, pane);
}
}
@@ -346,7 +341,8 @@ pub fn diffSpan(old: []const u8, new: []const u8) Span {
}
pub fn noteReplace(p: *Pardes, id: usize, on_tag: bool, old: []const u8, new: []const u8) void {
- if (!p.fs.scripted(id)) return;
+ const pane = p.panes[id] orelse return;
+ if (pane.fs.readers == 0) return;
const span = diffSpan(old, new);
if (span.removed == 0 and span.inserted == 0) return;
if (span.removed > 0) _ = noteAction(
@@ -378,17 +374,18 @@ pub fn noteAction(
flag: u32,
text: []const u8,
) bool {
- if (!p.fs.scripted(id)) return false;
+ const pane = p.panes[id] orelse return false;
+ if (pane.fs.readers == 0) return false;
var buf: [max_record_text + 64]u8 = undefined;
const record = formatRecord(&buf, p.fs.origin, action, q0, q1, flag, text);
- p.fs.panes[id].events.push(p.gpa, record);
+ pane.fs.events.push(p.gpa, record);
p.fs.news = true;
return true;
}
pub fn notePtyOutput(p: *Pardes, id: usize, bytes: []const u8) void {
if (id >= MAX_PANES or bytes.len == 0) return;
- const pf = &p.fs.panes[id];
+ const pf = &(p.panes[id] orelse return).fs;
if (pf.pty_readers == 0) return;
var off: usize = 0;
while (off < bytes.len) {
@@ -486,7 +483,7 @@ test "event records are acme's bytes, one per read, and .again when empty" {
const event = Node.of(serial, .event);
_ = noteAction(p, 0, .body_exec, 1, 4, flag_builtin, "sg ");
- try testing.expect(p.fs.panes[0].events.empty());
+ try testing.expect(p.panes[0].?.fs.events.empty());
const h = call(p, .{ .tag = 10, .op = .open, .node = event });
try testing.expect(h.reply.handle != 0);
@@ -570,19 +567,19 @@ test "one event reader at a time, and a writer still holds the pane" {
try testing.expectEqualStrings(tree.e_in_use, second.reply.ename);
const writer = call(p, .{ .tag = 13, .op = .open, .node = event, .omode = 1 });
try testing.expectEqual(Status.ok, writer.reply.status);
- try testing.expectEqual(@as(u16, 2), p.fs.panes[0].readers);
+ try testing.expectEqual(@as(u16, 2), p.panes[0].?.fs.readers);
try testing.expectEqual(@as(u16, 2), p.fs.listeners);
_ = call(p, .{ .tag = 14, .op = .release, .node = event, .handle = writer.reply.handle });
- try testing.expectEqual(@as(u16, 1), p.fs.panes[0].readers);
- try testing.expect(p.fs.scripted(0));
+ try testing.expectEqual(@as(u16, 1), p.panes[0].?.fs.readers);
+ try testing.expect(p.panes[0].?.fs.readers != 0);
_ = call(p, .{ .tag = 15, .op = .release, .node = Node.of(serialOf(p), .body) });
try testing.expectEqual(@as(u16, 1), p.fs.listeners);
_ = call(p, .{ .tag = 16, .op = .release, .node = event, .handle = reader.reply.handle });
try testing.expectEqual(@as(u16, 0), p.fs.listeners);
- try testing.expect(!p.fs.scripted(0));
+ try testing.expect(p.panes[0].?.fs.readers == 0);
_ = call(p, .{ .tag = 17, .op = .release, .node = event });
try testing.expectEqual(@as(u16, 0), p.fs.listeners);
// Once it closed, the next reader gets in.