diff options
Diffstat (limited to 'src/detached')
| -rw-r--r-- | src/detached/server.zig | 27 | ||||
| -rw-r--r-- | src/detached/wire.zig | 8 |
2 files changed, 21 insertions, 14 deletions
diff --git a/src/detached/server.zig b/src/detached/server.zig index ac9af2ee..3e98fc9d 100644 --- a/src/detached/server.zig +++ b/src/detached/server.zig @@ -156,7 +156,8 @@ pub const Session = struct { inotify_fd: c_int = -1, ninep: ?*ninep_io.Listener = null, ninep_pending: bool = false, - /// Set by the 9P runner's tasks: a request waits for `tick`. + /// A 9P request changed the core since the wake byte was last drained: + /// the next poll returns at once, to draw it. ninep_wake: std.atomic.Value(bool) = .init(false), watches: file_watch.Table = @splat(null), check_files: bool = false, @@ -240,7 +241,7 @@ pub const Session = struct { file_watch.watchPane(s.inotify_fd, &s.watches, @intCast(pane), null, 0, .{ .text = 0 }); _ = file_watch.applyThemeEffect(s.core, s.gpa, s.inotify_fd, &s.watches, 0, false, false); s.check_files = false; - if (s.ninep) |listener| listener.reset(s.core); + if (s.ninep) |listener| listener.reset(replacement); s.ninep_pending = false; replacement.host = s.host(); s.core.deinit(); @@ -587,7 +588,7 @@ pub const Session = struct { if (s.origins()) |c| s.send(c, .detach); } - /// The 9P runner has a request for `tick`: wake the poll loop. + /// A 9P request changed the core: wake the poll loop to draw it. fn wakeNinep(ctx: ?*anyopaque) void { const s = of(ctx); s.ninep_wake.store(true, .release); @@ -596,7 +597,7 @@ pub const Session = struct { fn pollFrame(ctx: ?*anyopaque) void { const s = of(ctx); - if (s.ninep) |l| s.ninep_pending = l.tick(s.core).pending; + if (s.ninep) |l| s.ninep_pending = l.tick().pending; for (&s.ptys, 0..) |*pt, pane| { if (pt.fd < 0) continue; var lbuf: [pardes.memory.limits.host_path_cap + 1]u8 = undefined; @@ -805,11 +806,18 @@ pub const Session = struct { } } } - if (n == 0) return nap(if (timeout_ms == 0) 16 else timeout_ms); + // The wait is the 9P connections' turn with the core. + if (n == 0) { + pardes.turn.rest(); + defer pardes.turn.wake(); + return nap(if (timeout_ms == 0) 16 else timeout_ms); + } var timeout: c_int = if (timeout_ms == 0) -1 else @intCast(@min(timeout_ms, std.math.maxInt(c_int))); if (s.nextWake(now)) |due| timeout = if (timeout < 0) due else @min(timeout, due); if (completed or s.check_files or regridded or s.ninep_pending) timeout = 0; + pardes.turn.rest(); const ready = libc.poll(&fds, @intCast(n), timeout); + pardes.turn.wake(); if (ready > 0) s.dispatch(fds[0..n], src[0..n]); _ = s.drainCompletions(true); s.expire(monotonicMs()); @@ -1134,18 +1142,17 @@ pub fn run(init: std.process.Init, opts: pardes.Options, name: []const u8) !void return error.NoSocket; } - session.ninep = ninep_io.listen(init.io, gpa, opts.ninep_name, name, opts.ninep_tcp, opts.ninep_quic); + session.ninep = ninep_io.listen(init.io, gpa, core, opts.ninep_name, name, opts.ninep_tcp, opts.ninep_quic); if (session.ninep == null) return error.ListenFailed; - session.ninep.?.setWake(&session, Session.wakeNinep); - core.fs.socket_path = session.ninep.?.path(); - core.fs.tcp_address = session.ninep.?.tcp_address; - core.fs.quic_address = session.ninep.?.quic_address; + session.ninep.?.wake_ctx = &session; + session.ninep.?.wake = Session.wakeNinep; const h = session.host(); core.host = h; while (core.nextEffect()) |effect| core.perform(effect); session.in_loop = true; while (!session.core.quit) { + pardes.turn.restoreSettled(); try session.core.pump(h); if (session.core.quit) break; if (session.core.takeRestore()) |path| restore: { diff --git a/src/detached/wire.zig b/src/detached/wire.zig index 6805d980..20b5c093 100644 --- a/src/detached/wire.zig +++ b/src/detached/wire.zig @@ -509,7 +509,7 @@ const Ul = @FieldType(pardes.CellStyle, "ul"); /// which is the whole property the six hand-written switches this replaced /// existed for, in a form that cannot fall out of step. A variant that has to /// travel under a DIFFERENT name than the core's gets an arm of its own before -/// the `inline else`, exactly as `clientTag` keeps `.fs_req`. +/// the `inline else`, exactly as `clientTag` keeps the machine-local reports. fn putUl(w: *Writer, u: Ul) Error!void { try w.putByte(switch (u) { inline else => |t| @intFromEnum(@field(UlTag, @tagName(t))), @@ -819,7 +819,7 @@ fn clientTag(msg: ClientMsg) ClientTag { return switch (msg) { .event => |ev| switch (ev) { // Machine-local reports and 9P requests belong to the session owner. - .output, .eof, .lsp_resp, .pipe_resp, .file_changed, .tick, .fs_req => unreachable, + .output, .eof, .lsp_resp, .pipe_resp, .file_changed, .tick => unreachable, inline else => |_, t| @field(ClientTag, @tagName(t)), }, inline else => |_, t| @field(ClientTag, @tagName(t)), @@ -946,7 +946,7 @@ pub fn encodeClient(out: []u8, msg: ClientMsg) Error![]const u8 { .touch_scroll => |v| try w.putF32(v), .pointer_leave => {}, // See `clientTag`: no tag, so nothing to encode. - .output, .eof, .lsp_resp, .pipe_resp, .file_changed, .tick, .fs_req => unreachable, + .output, .eof, .lsp_resp, .pipe_resp, .file_changed, .tick => unreachable, }, } try finishMessage(&w, at); @@ -1076,7 +1076,7 @@ pub fn clientBound(msg: ClientMsg) usize { .paste => |b| b.len, .command => |line| line.len, // See `clientTag`: not on this wire in this direction. - .output, .eof, .lsp_resp, .pipe_resp, .file_changed, .tick, .fs_req => unreachable, + .output, .eof, .lsp_resp, .pipe_resp, .file_changed, .tick => unreachable, }, }; } |
