P0 fix: Mutex/RwLock poison recovery for webdav_locks and webdav_version
Some checks failed
Test / build (push) Has been cancelled
Test / test (push) Has been cancelled

- Add recover_mutex() helper in webdav_locks.rs
- Add recover_rwlock() helper in webdav_version.rs
- Replace all .unwrap() calls with recovery pattern
- Tests: 288 passed, 0 failed
This commit is contained in:
Warren
2026-06-21 18:11:48 +08:00
parent 1408646424
commit b71510b2e8
2 changed files with 37 additions and 17 deletions

View File

@@ -7,6 +7,16 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
use uuid::Uuid;
use xmltree::Element;
fn recover_mutex<T>(result: std::sync::LockResult<T>) -> T {
match result {
Ok(guard) => guard,
Err(e) => {
log::warn!("Mutex poisoned in webdav_locks, recovering");
e.into_inner()
}
}
}
/// Serializable lock representation for JSON persistence
#[derive(Debug, Clone, Serialize, Deserialize)]
struct PersistedLock {
@@ -142,7 +152,7 @@ impl DavLockSystem for PersistedLs {
let principal_owned = principal.map(|s| s.to_string());
let owner_owned = owner.map(|o| Box::new(o.clone()));
Box::pin(async move {
let mut all = locks.lock().unwrap();
let mut all = recover_mutex(locks.lock());
cleanup_expired_locks(&mut all, &locks_file);
let path_str = path2.to_string();
for existing in all.iter() {
@@ -186,7 +196,7 @@ impl DavLockSystem for PersistedLs {
let locks_file = self.locks_file.clone();
let token_owned = token.to_string();
Box::pin(async move {
let mut all = locks.lock().unwrap();
let mut all = recover_mutex(locks.lock());
let before = all.len();
all.retain(|l| !(l.path.to_string() == path_str && l.token == token_owned));
if all.len() == before {
@@ -213,7 +223,7 @@ impl DavLockSystem for PersistedLs {
let token_owned = token.to_string();
let locks_file = self.locks_file.clone();
Box::pin(async move {
let mut all = locks.lock().unwrap();
let mut all = recover_mutex(locks.lock());
let existing = all.iter_mut().find(|l| l.path.to_string() == path_str && l.token == token_owned);
match existing {
Some(lock) => {
@@ -247,7 +257,7 @@ impl DavLockSystem for PersistedLs {
let submitted = submitted_tokens.to_vec();
let locks_file = self.locks_file.clone();
Box::pin(async move {
let mut all = locks.lock().unwrap();
let mut all = recover_mutex(locks.lock());
cleanup_expired_locks(&mut all, &locks_file);
for existing in all.iter() {
let ep = existing.path.to_string();
@@ -269,7 +279,7 @@ impl DavLockSystem for PersistedLs {
let path_str = path.to_string();
let locks_file = self.locks_file.clone();
Box::pin(async move {
let mut all = locks.lock().unwrap();
let mut all = recover_mutex(locks.lock());
cleanup_expired_locks(&mut all, &locks_file);
let mut result: Vec<DavLock> = all
.iter()
@@ -289,7 +299,7 @@ impl DavLockSystem for PersistedLs {
let prefix = path.to_string().trim_end_matches('/').to_string();
let locks_file = self.locks_file.clone();
Box::pin(async move {
let mut all = locks.lock().unwrap();
let mut all = recover_mutex(locks.lock());
let before = all.len();
all.retain(|l| {
let lp = l.path.to_string().trim_end_matches('/').to_string();