fix: a panic on one thread no longer takes the whole app down

Every shared lock was std::sync::Mutex with lock().unwrap() (~150 sites),
so a panic in any session's reader or callback poisoned the lock and the
next UI frame panicked too, dropping every open session. Locks are now
parking_lot::Mutex (no poisoning; already in the dependency tree), and a
panic hook reports worker panics as an error toast instead of the session
silently stopping (F3, F4).
This commit is contained in:
Andy Dixon
2026-10-12 09:07:32 +01:00
parent afec95bb36
commit f09300fd95
28 changed files with 252 additions and 221 deletions
+7 -6
View File
@@ -2,8 +2,9 @@
//! `Profile::host`, line settings come from `Profile::serial`. Same conventions as the other
//! clients: blocking `connect`, an own reader thread, `on_close` exactly once (unplug included).
use parking_lot::Mutex;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use serialport::{DataBits, FlowControl, Parity, SerialPort, StopBits};
@@ -45,7 +46,7 @@ impl SerialClient {
/// Opens and configures the port, applies DTR/RTS, and starts the reader thread.
pub fn connect(&self) -> crate::Result<()> {
let inner = &self.inner;
if inner.port.lock().unwrap().is_some() {
if inner.port.lock().is_some() {
return Err("already connected".into());
}
if inner.path.is_empty() {
@@ -82,7 +83,7 @@ impl SerialClient {
reader.set_timeout(READ_POLL)?;
let stop = Arc::new(AtomicBool::new(false));
{
let mut guard = inner.port.lock().unwrap();
let mut guard = inner.port.lock();
if guard.is_some() {
return Err("already connected".into());
}
@@ -128,11 +129,11 @@ impl SerialClient {
}
pub fn is_connected(&self) -> bool {
self.inner.port.lock().unwrap().is_some()
self.inner.port.lock().is_some()
}
fn with_port(&self, f: impl FnOnce(&mut Box<dyn SerialPort>) -> crate::Result<()>) -> crate::Result<()> {
let mut guard = self.inner.port.lock().unwrap();
let mut guard = self.inner.port.lock();
let (port, _) = guard.as_mut().ok_or("not connected")?;
f(port)
}
@@ -165,7 +166,7 @@ impl Inner {
}
fn close(&self) {
let taken = self.port.lock().unwrap().take();
let taken = self.port.lock().take();
if let Some((port, stop)) = taken {
stop.store(true, Ordering::SeqCst);
drop(port);