Fix query response wait confusion over builtin read

Every reader gets their own wait handle which is wrong and not actually
needed - it's a singleton.  We should probaly make it global. Let's
do an intermediate solution for now -- not much time this weekend ;).

Fixes #11110
This commit is contained in:
Johannes Altmanninger
2025-02-01 09:08:04 +01:00
parent cbedfc8a64
commit 66e2b6d8c1
4 changed files with 72 additions and 35 deletions

View File

@@ -25,6 +25,7 @@
use std::os::unix::ffi::OsStrExt;
use std::ptr;
use std::sync::atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering};
use std::sync::{Mutex, MutexGuard};
// The range of key codes for inputrc-style keyboard functions.
pub const R_END_INPUT_FUNCTIONS: usize = (ReadlineCmd::ReverseRepeatJump as usize) + 1;
@@ -801,7 +802,7 @@ fn try_readch(&mut self, blocking: bool) -> Option<CharEvent> {
reader,
"Received interrupt key, giving up waiting for response from terminal"
);
let ok = self.unblock_input();
let ok = unblock_input(self.blocking_wait());
assert!(ok);
}
continue;
@@ -1062,7 +1063,9 @@ fn parse_csi(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
if code != 0 || c != b'M' || modifiers.is_some() {
return None;
}
let Some(wait) = self.blocking_wait() else {
let wait_guard = self.blocking_wait();
let Some(wait) = &*wait_guard else {
drop(wait_guard);
self.on_mouse_left_click(position);
return None;
};
@@ -1109,7 +1112,8 @@ fn parse_csi(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
return invalid_sequence(buffer);
};
FLOG!(reader, "Received cursor position report y:", y, "x:", x);
let Some(BlockingWait::CursorPosition(wait)) = self.blocking_wait() else {
let wait_guard = self.blocking_wait();
let Some(BlockingWait::CursorPosition(wait)) = &*wait_guard else {
CURSOR_POSITION_REPORTING_SUPPORTED.store(true);
return None;
};
@@ -1124,6 +1128,7 @@ fn parse_csi(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
ImplicitEvent::ScrollbackPushContinuation(y)
}
};
drop(wait_guard);
self.push_front(CharEvent::Implicit(continuation));
return None;
}
@@ -1536,15 +1541,13 @@ fn drop_leading_readline_events(&mut self) {
}
}
fn blocking_wait(&self) -> Option<&BlockingWait> {
None
fn blocking_wait(&self) -> MutexGuard<Option<BlockingWait>> {
static NO_WAIT: Mutex<Option<BlockingWait>> = Mutex::new(None);
NO_WAIT.lock().unwrap()
}
fn is_blocked(&self) -> bool {
false
}
fn unblock_input(&mut self) -> bool {
false
}
fn on_mouse_left_click(&mut self, _position: ViewportPosition) {}
@@ -1559,7 +1562,7 @@ fn enqueue_interrupt_key(&mut self) {
let vintr = shell_modes().c_cc[libc::VINTR];
if vintr != 0 {
let interrupt_evt = CharEvent::from_key(Key::from_single_byte(vintr));
if self.unblock_input() {
if unblock_input(self.blocking_wait()) {
FLOG!(
reader,
"Received interrupt, giving up on waiting for terminal response"
@@ -1590,6 +1593,14 @@ fn has_lookahead(&self) -> bool {
}
}
pub(crate) fn unblock_input(mut wait_guard: MutexGuard<Option<BlockingWait>>) -> bool {
if wait_guard.is_none() {
return false;
}
*wait_guard = None;
true
}
fn invalid_sequence(buffer: &[u8]) -> Option<Key> {
FLOG!(
reader,