refactor: replace lock unwraps with poison-aware helpers
Add SoulseekRs::LockPoisoned variant and a small RwLockExt/MutexExt helper module exposing read_safe/write_safe/lock_safe that map PoisonError to that variant. Walk every non-test lock acquisition across client, peer/server actors, peer registry, listener and the thread pool: propagate via ? where the function returns Result, log and degrade to a sensible default (return early, false, None, empty) where it does not. Client::connect now returns Result so the CLI can surface the failure instead of panicking.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use crate::error::{Result, SoulseekRs};
|
||||
|
||||
pub trait RwLockExt<T> {
|
||||
fn read_safe(&self) -> Result<RwLockReadGuard<'_, T>>;
|
||||
fn write_safe(&self) -> Result<RwLockWriteGuard<'_, T>>;
|
||||
}
|
||||
|
||||
impl<T> RwLockExt<T> for RwLock<T> {
|
||||
fn read_safe(&self) -> Result<RwLockReadGuard<'_, T>> {
|
||||
self.read().map_err(|_| SoulseekRs::LockPoisoned)
|
||||
}
|
||||
|
||||
fn write_safe(&self) -> Result<RwLockWriteGuard<'_, T>> {
|
||||
self.write().map_err(|_| SoulseekRs::LockPoisoned)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MutexExt<T> {
|
||||
fn lock_safe(&self) -> Result<MutexGuard<'_, T>>;
|
||||
}
|
||||
|
||||
impl<T> MutexExt<T> for Mutex<T> {
|
||||
fn lock_safe(&self) -> Result<MutexGuard<'_, T>> {
|
||||
self.lock().map_err(|_| SoulseekRs::LockPoisoned)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#[macro_use]
|
||||
pub mod logger;
|
||||
pub mod lock;
|
||||
pub mod md5;
|
||||
pub mod thread_pool;
|
||||
pub mod zlib;
|
||||
|
||||
@@ -2,6 +2,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex, mpsc};
|
||||
use std::thread;
|
||||
|
||||
use crate::utils::lock::MutexExt;
|
||||
|
||||
type Job = Box<dyn FnOnce() + Send + 'static>;
|
||||
|
||||
enum Message {
|
||||
@@ -91,7 +93,10 @@ impl Worker {
|
||||
) -> Worker {
|
||||
let thread = thread::spawn(move || {
|
||||
loop {
|
||||
let message = receiver.lock().unwrap().recv();
|
||||
let message = match receiver.lock_safe() {
|
||||
Ok(rx) => rx.recv(),
|
||||
Err(_) => break,
|
||||
};
|
||||
match message {
|
||||
Ok(Message::NewJob(job)) => {
|
||||
// let active =
|
||||
|
||||
Reference in New Issue
Block a user