P0 fix: Mutex/RwLock poison recovery for webdav_locks and webdav_version
- 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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user