From 28c814aa5cfea23e8950ef007916ffc5d089288d Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Sun, 27 Sep 2026 20:09:02 -0300 Subject: Hold a read that has nothing yet and answer it when its file has news A following log, event, pty/data or a pty/run before its answer used to answer .again and wait for a wakeAll, which only the parked-write path asked for, so the band-aid had every queue push set turn.parked. Now the core keeps such a read (ctlfs.hold) and, as the turn is given up after anything that queued a record, ran a command out or closed a pane, answers it on its own connection, the way factotum answers the log reads it keeps and acme an event read. Only a read the engine still holds parked is answered, because cloud9 tells the backend nothing of a Tflush, so a flushed read spends no record. Co-Authored-By: Claude Opus 5.5 --- src/ninep/events.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/ninep/events.zig') diff --git a/src/ninep/events.zig b/src/ninep/events.zig index bd5fecf3..6b8c744e 100644 --- a/src/ninep/events.zig +++ b/src/ninep/events.zig @@ -50,10 +50,6 @@ pub const Queue = struct { q.buf.shrinkRetainingCapacity(q.buf.items.len - 4); return; }; - // A read parked on this queue is retried only when the turn is next - // given up with `parked` set; without it a follower sleeps until some - // unrelated request happens to park. - pardes.turn.parked = true; } pub fn peek(q: *const Queue) ?[]const u8 { @@ -105,7 +101,7 @@ pub fn pending(q: *const Queue) u64 { return record.len; } -/// One record per read; `.again` parks the read until a record arrives. +/// One record per read; `.again` holds the read until a record arrives. pub fn readQueue(p: *Pardes, req: Req, q: *Queue) Reply { const record = q.peek() orelse return .{ .tag = req.tag, .status = .again }; if (req.size < record.len) return Reply.fail(req.tag, E.INVAL); @@ -129,6 +125,7 @@ pub fn noteInstall(p: *Pardes, id: usize) void { pub fn noteRetire(p: *Pardes, id: usize, pane: *Pane) void { if (id >= MAX_PANES) return; tree.pty.shellGone(p, id); + 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; return; @@ -174,6 +171,7 @@ fn pushLog(p: *Pardes, record: []u8) void { while (end > 0 and record[end] & 0xC0 == 0x80) end -= 1; record[end] = '\n'; p.fs.log.push(p.gpa, record[0 .. end + 1]); + p.fs.news = true; } /// An open freezes the ring's text, so `cat log` answers what happened lately @@ -384,6 +382,7 @@ pub fn noteAction( 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); + p.fs.news = true; return true; } @@ -397,6 +396,7 @@ pub fn notePtyOutput(p: *Pardes, id: usize, bytes: []const u8) void { pf.pty_out.push(p.gpa, bytes[off..][0..n]); off += n; } + p.fs.news = true; } const EventRecord = struct { action: Action, q0: u32, q1: u32 }; -- cgit v1.3