diff options
| author | Eric Yue <jiacheng.yue@foxmail.com> | 2026-09-28 04:16:55 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-27 22:16:55 +0200 |
| commit | c210c953e454882c5ef3cd366bcd4b53b7c64791 (patch) | |
| tree | 785c9325e0ac9ce3d647aa5dd17e063df38dd3e5 /src/server/headless.rs | |
| parent | 87c08c6b7a1dbd250fa3a8e9424a47b3176f99eb (diff) | |
fix: bound external event batches in the server loop (#4671)
Diffstat (limited to 'src/server/headless.rs')
| -rw-r--r-- | src/server/headless.rs | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/server/headless.rs b/src/server/headless.rs index fe8a67e8..da3baf30 100644 --- a/src/server/headless.rs +++ b/src/server/headless.rs @@ -82,6 +82,11 @@ mod render; mod retained_surface; mod surface_interest; +// Producers can refill even a bounded channel while it is being drained. +// Yield to scheduled work and rendering between batches; select! below +// immediately wakes for any messages left in either external queue. +const EXTERNAL_EVENT_DRAIN_LIMIT: usize = 64; + pub use bootstrap::run_server; use lifecycle::wait_for_live_handoff_response_write; #[cfg(unix)] @@ -1011,7 +1016,10 @@ impl HeadlessServer { /// Drains server events from the dedicated channel. fn drain_server_events(&mut self) -> bool { let mut changed = false; - while !self.should_quit.load(Ordering::Acquire) { + for _ in 0..EXTERNAL_EVENT_DRAIN_LIMIT { + if self.should_quit.load(Ordering::Acquire) { + break; + } let Ok(ev) = self.server_event_rx.try_recv() else { break; }; @@ -2788,7 +2796,10 @@ impl HeadlessServer { /// During shutdown, remaining requests get a `server_unavailable` error. fn drain_api_requests_with_shutdown_check(&mut self) -> bool { let mut changed = false; - while !self.should_quit.load(Ordering::Acquire) { + for _ in 0..EXTERNAL_EVENT_DRAIN_LIMIT { + if self.should_quit.load(Ordering::Acquire) { + break; + } let Ok(msg) = self.app.api_rx.try_recv() else { break; }; |
