diff --git a/packages/process-daemon/README.md b/packages/process-daemon/README.md index d8693b9bba61..b26a1fca9e47 100644 --- a/packages/process-daemon/README.md +++ b/packages/process-daemon/README.md @@ -68,7 +68,7 @@ that wakes partial requests and blocked subscription writes before joining. On Unix the daemon loop sleeps in `poll(2)` on the listener and a private wake socket pair until a connection arrives, a stop or ownership change wakes it, an ownership deadline is due, or a two-second safety net elapses. Windows still -polls every 10 ms. +polls every 25 ms. The Windows named-pipe backend keeps protocol 7 and the registration fields `instance_id`, `pid`, `protocol`, `socket`, and `token`. Treat `socket` as an opaque @@ -332,7 +332,7 @@ coverage on their own. On Windows, normal root-child exit hands the ConPTY master to the existing child-wait worker for closing. The actor and reader continue draining until the real output-pipe EOF; only then is the final exit event published. The worker -checks the root's wait handle at 10 ms intervals. After the master is handed +checks the root's wait handle at 25 ms intervals. After the master is handed off, Windows input and resize requests fail with a child-exited error; final snapshots, rows, and replay remain readable until the terminal is removed. Unix post-exit PTY operations retain their existing behavior. diff --git a/packages/process-daemon/src/service/windows.rs b/packages/process-daemon/src/service/windows.rs index 81c8cd426514..3c69457ac457 100644 --- a/packages/process-daemon/src/service/windows.rs +++ b/packages/process-daemon/src/service/windows.rs @@ -9,10 +9,12 @@ use windows_sys::Win32::{ use super::ActorMessage; +const EXIT_POLL_INTERVAL: Duration = Duration::from_millis(25); + /// Keep blocking ClosePseudoConsole off the actor/reader without introducing /// another worker. The actor hands its unique master here on root exit or on /// teardown; closing it then produces the real output-pipe EOF. -/// Root-exit detection uses a 10 ms poll interval. After reaping, the +/// Root-exit detection uses a 25 ms poll interval. After reaping, the /// worker blocks on the close channel rather than continuing to poll. pub(super) fn wait_and_close( mut child: Box, @@ -37,7 +39,7 @@ pub(super) fn wait_and_close( let request = if reported { close.recv().map_err(|_| RecvTimeoutError::Disconnected) } else { - close.recv_timeout(Duration::from_millis(10)) + close.recv_timeout(EXIT_POLL_INTERVAL) }; match request { Ok(master) => { diff --git a/packages/process-daemon/src/transport/mod.rs b/packages/process-daemon/src/transport/mod.rs index a7ff72f22b5f..614c3dc38371 100644 --- a/packages/process-daemon/src/transport/mod.rs +++ b/packages/process-daemon/src/transport/mod.rs @@ -4,7 +4,7 @@ //! frame before the peer has had a chance to read it. //! //! The daemon blocks in `Listener::wait` (Unix: poll(2) on the listener and a -//! `Wake` socket pair; Windows: still a 10 ms poll) and then calls `accept` until +//! `Wake` socket pair; Windows: still a 25 ms poll) and then calls `accept` until //! it returns `None`. Connection reads/writes run only on its handler threads. A //! separate `Cancellation` can wake both directions without waiting for either //! handler or peer. `finish_response` and a disconnect monitor's `finish` are diff --git a/packages/process-daemon/src/transport/windows.rs b/packages/process-daemon/src/transport/windows.rs index 1919ea15a91a..edfdc3d92df6 100644 --- a/packages/process-daemon/src/transport/windows.rs +++ b/packages/process-daemon/src/transport/windows.rs @@ -38,6 +38,8 @@ use security::PrivateSecurity; const BUFFER_BYTES: u32 = 64 * 1024; const CONNECT_TIMEOUT: Duration = Duration::from_secs(5); const COMPLETION_TIMEOUT: Duration = Duration::from_secs(2); +/// Interim idle poll until `wait` blocks on the pending connect and a stop event. +const POLL_INTERVAL: Duration = Duration::from_millis(25); pub(crate) struct Listener { endpoint: Vec, @@ -83,9 +85,9 @@ impl Listener { self.pending.operation.pipe.cancel(); } - /// Windows keeps the 10 ms poll for now; the caller then polls `accept`. + /// Windows keeps a 25 ms poll for now; the caller then polls `accept`. pub fn wait(&self, _wake: &Wake, listen: bool, timeout: Duration) -> io::Result { - thread::sleep(timeout.min(Duration::from_millis(10))); + thread::sleep(timeout.min(POLL_INTERVAL)); // `timed_out` stays false: Windows cannot tell, and the missed-wake detector must stay off. Ok(Readiness { connection: listen, @@ -102,7 +104,7 @@ pub(crate) struct Readiness { pub timed_out: bool, } -/// Windows keeps the 10 ms poll for now, so notify is a no-op. +/// Windows keeps a 25 ms poll for now, so notify is a no-op. pub(crate) struct Wake; impl Wake {