fix(tui): bound input event draining
handle_input() previously drained terminal events in an unbounded while-poll loop, so a continuously-ready input stream could keep the frontend inside handle_input() indefinitely, starving managed-event processing, completion checks, peer-close stop policy, and rendering in the outer run_tui() loop. Bound each call to at most INPUT_EVENT_WORK_BUDGET (128) polled terminal events, mirroring the MANAGED_EVENT_WORK_BUDGET pattern already used for managed event draining. All polled events count against the budget, including ignored/unknown/release events, so a stream of non-actionable input can't bypass the bound. Remaining events are left queued for the next outer-loop iteration rather than dropped. Quit/Ctrl-C now also breaks out of the drain immediately after being handled, since there is no benefit to consuming further buffered input before the outer loop can request managed shutdown.
This commit is contained in:
1 file changed
+6
-1
@@ -26,6 +26,7 @@ use irtt_client::managed::{
|
||||
const RENDER_INTERVAL: Duration = Duration::from_millis(250);
|
||||
const TUI_WAIT_SLICE: Duration = Duration::from_millis(20);
|
||||
const MANAGED_EVENT_CAPACITY: usize = 16_384;
|
||||
const INPUT_EVENT_WORK_BUDGET: usize = 128;
|
||||
|
||||
pub fn run_tui(
|
||||
args: TuiArgs,
|
||||
@@ -216,7 +217,10 @@ fn drain_final_tui_events(
|
||||
}
|
||||
fn handle_input(state: &mut TuiState, shutdown_requested: &AtomicBool) -> io::Result<bool> {
|
||||
let mut force_render = false;
|
||||
while event::poll(Duration::ZERO)? {
|
||||
for _ in 0..INPUT_EVENT_WORK_BUDGET {
|
||||
if !event::poll(Duration::ZERO)? {
|
||||
break;
|
||||
}
|
||||
let Event::Key(key) = event::read()? else {
|
||||
continue;
|
||||
};
|
||||
@@ -231,6 +235,7 @@ fn handle_input(state: &mut TuiState, shutdown_requested: &AtomicBool) -> io::Re
|
||||
state.quit_requested = true;
|
||||
shutdown_requested.store(true, Ordering::Relaxed);
|
||||
force_render = true;
|
||||
break;
|
||||
}
|
||||
KeyCode::Char('r') => {
|
||||
state.clear_visible_history();
|
||||
|
||||
Reference in new issue
Block a user