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:
michel
2026-04-26 12:32:46 +02:00
parent e1ee3ac493
commit 2722552e35
10 changed files with 473 additions and 164 deletions
+22 -8
View File
@@ -9,6 +9,7 @@ use crate::client::{ClientContext, ClientOperation};
use crate::message::{Message, MessageReader};
use crate::peer::{ConnectionType, DownloadPeer, Peer};
use crate::types::Download;
use crate::utils::lock::RwLockExt;
use crate::{DownloadStatus, debug, error, info, trace};
const PEER_INIT_MESSAGE_CODE: u8 = 1;
@@ -82,7 +83,13 @@ fn extract_download_from_buffer(
username, token
);
let context = client_context.read().unwrap();
let context = match client_context.read_safe() {
Ok(c) => c,
Err(e) => {
error!("[listener] client context lock: {}", e);
return None;
}
};
let download = context.get_download_by_token(token).cloned();
if download.is_none() {
@@ -104,7 +111,13 @@ fn handle_peer_connection(
_peer_ip: &str,
_peer_port: u16,
) {
let client_context = context.client_context.read().unwrap();
let client_context = match context.client_context.read_safe() {
Ok(c) => c,
Err(e) => {
error!("[listener] handle_peer_connection lock: {}", e);
return;
}
};
if let Some(ref registry) = client_context.peer_registry {
match registry.register_peer(peer.clone(), Some(stream), Some(reader)) {
Ok(_) => (),
@@ -158,14 +171,15 @@ fn handle_file_connection(
) {
Ok((download, filename)) => {
let _ = download.sender.send(DownloadStatus::Completed);
context
.client_context
.write()
.unwrap()
.update_download_with_status(
match context.client_context.write_safe() {
Ok(mut ctx) => ctx.update_download_with_status(
download.token,
DownloadStatus::Completed,
);
),
Err(e) => {
error!("[listener] handle_file_connection write: {}", e)
}
}
info!(
"Successfully downloaded {} bytes to {}",
download.size, filename