Make terminal query data state a RefCell instead of mutex

We never need to access this from other threads, so a Mutex is overkill.
Leave behind stale variable names like "wait_guard" to be cleaned up by the
next commit.

Since TestInputEventQueuer is used concurrently in tests,
give it its own private object, to avoid borrowing conflicts.

Same for fish_key_reader; this fixes the issue that fish_key_reader potentially
reads keyboard input before a query is finished.
This commit is contained in:
Johannes Altmanninger
2025-04-28 20:35:34 +02:00
parent e7c9f6d47e
commit 788eddd0e8
5 changed files with 23 additions and 13 deletions

View File

@@ -27,12 +27,12 @@
use crate::wchar::{encode_byte_to_char, prelude::*};
use crate::wutil::encoding::{mbrtowc, mbstate_t, zero_mbstate};
use crate::wutil::fish_wcstol;
use std::cell::{RefCell, RefMut};
use std::collections::VecDeque;
use std::os::fd::RawFd;
use std::os::unix::ffi::OsStrExt;
use std::ptr;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::{Mutex, MutexGuard};
use std::time::Duration;
// The range of key codes for inputrc-style keyboard functions.
@@ -1628,10 +1628,7 @@ fn drop_leading_readline_events(&mut self) {
}
}
fn blocking_wait(&self) -> MutexGuard<Option<BlockingWait>> {
static NO_WAIT: Mutex<Option<BlockingWait>> = Mutex::new(None);
NO_WAIT.lock().unwrap()
}
fn blocking_wait(&self) -> RefMut<'_, Option<BlockingWait>>;
fn is_blocked(&self) -> bool {
self.blocking_wait().is_some()
}
@@ -1753,7 +1750,7 @@ pub(crate) fn decode_input_byte(
invalid(out_seq, || FLOG!(reader, "Illegal codepoint"))
}
pub(crate) fn unblock_input(mut wait_guard: MutexGuard<Option<BlockingWait>>) -> bool {
pub(crate) fn unblock_input(mut wait_guard: RefMut<'_, Option<BlockingWait>>) -> bool {
if wait_guard.is_none() {
return false;
}
@@ -1787,12 +1784,14 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// A simple, concrete implementation of InputEventQueuer.
pub struct InputEventQueue {
data: InputData,
blocking_wait: RefCell<Option<BlockingWait>>,
}
impl InputEventQueue {
pub fn new(in_fd: RawFd) -> Self {
Self {
data: InputData::new(in_fd),
blocking_wait: RefCell::new(None),
}
}
}
@@ -1811,6 +1810,9 @@ fn select_interrupted(&mut self) {
self.enqueue_interrupt_key();
}
}
fn blocking_wait(&self) -> RefMut<'_, Option<BlockingWait>> {
self.blocking_wait.borrow_mut()
}
}
fn parse_hex(hex: &[u8]) -> Option<Vec<u8>> {