From eb2428115588004a8bc04a09d45fb1104f727882 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 13:58:36 -0300 Subject: Unattended messages expire in the detached session's loop, not as a 9P request is served serveFs expired them, but a read is answered while a step is out in a syscall, because reads change nothing, and this one changed pane messages and needs_frame from under the step. The detached session's loop now expires them between steps, and while nobody is attached and a message is up it looks again every 100 ms rather than waiting for something to wake it. Co-Authored-By: Claude Opus 5.5 --- src/Messages.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/Messages.zig') diff --git a/src/Messages.zig b/src/Messages.zig index 0652f974..00352afe 100644 --- a/src/Messages.zig +++ b/src/Messages.zig @@ -208,7 +208,9 @@ fn nowMs() i64 { /// With no frontend attached no input dismisses a message, and a detached /// session's /screen and messages kept what was said an hour ago: each /// pane's lines go once its newest has been up `message_linger_ms`, on the -/// clock, checked as the core is stepped or served. +/// clock, checked as the core is stepped and by the detached session's loop +/// between steps -- not as a 9P request is served, since a read is answered +/// while a step is out and must change nothing. /// ponytail: a pane's older lines go with its newest, not each on its own /// clock; the render pipeline's clock will give every line its own. pub fn expireUnattended(p: *Pardes) void { @@ -570,7 +572,10 @@ test "with no frontend attached a message goes once it has lingered, on the cloc // Detached with nobody attached: past its linger it is gone, and the // line above it with it. p.unattended = true; + // A read served meanwhile changes nothing; the session's loop expires. _ = p.serveFs(.{ .tag = 1, .op = .read, .node = @intFromEnum(ctlfs.TopFile.index), .size = 64 }); + try std.testing.expect(pane.msg_len > 0); + expireUnattended(p); try std.testing.expectEqual(@as(u16, 0), pane.msg_len); try std.testing.expectEqual(@as(u8, 0), pane.msg_older_len); // A fresh one stays until its linger is up. -- cgit v1.3