diff options
Diffstat (limited to 'src/detached/server.zig')
| -rw-r--r-- | src/detached/server.zig | 27 |
1 files changed, 17 insertions, 10 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: { |
