Fix lost wakeup in range_lock caused by waiting on an outdated waitqueue

This commit is contained in:
Ruize Tang
2024-10-17 17:27:05 +08:00
committed by Tate, Hongliang Tian
parent e5fd8e7477
commit 968389f550

View File

@ -2,7 +2,7 @@
use core::fmt; use core::fmt;
use ostd::sync::{RwMutexWriteGuard, WaitQueue}; use ostd::sync::{RwMutexWriteGuard, WaitQueue, Waiter};
use self::range::FileRangeChange; use self::range::FileRangeChange;
pub use self::{ pub use self::{
@ -229,7 +229,7 @@ impl RangeLockList {
req_lock, is_nonblocking req_lock, is_nonblocking
); );
loop { loop {
let conflict_lock; let (waiter, waker);
{ {
let mut list = self.inner.write(); let mut list = self.inner.write();
@ -237,22 +237,15 @@ impl RangeLockList {
if is_nonblocking { if is_nonblocking {
return_errno_with_message!(Errno::EAGAIN, "the file is locked"); return_errno_with_message!(Errno::EAGAIN, "the file is locked");
} }
(waiter, waker) = Waiter::new_pair();
conflict_lock = existing_lock.clone(); existing_lock.waitqueue.enqueue(waker);
} else { } else {
Self::insert_lock_into_list(&mut list, req_lock); Self::insert_lock_into_list(&mut list, req_lock);
return Ok(()); return Ok(());
} }
} }
conflict_lock.wait_until(|| { waiter.wait();
let list = self.inner.read();
if list.iter().any(|l| req_lock.conflict_with(l)) {
None
} else {
Some(())
}
});
} }
} }