mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 18:03:25 +00:00
Fix flock lost-wakeup bugs, replace RwMutex -> Mutex
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
d977fe54c6
commit
e5fd8e7477
@ -2,7 +2,7 @@
|
|||||||
use alloc::fmt;
|
use alloc::fmt;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
use ostd::sync::WaitQueue;
|
use ostd::sync::{WaitQueue, Waiter};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{file_handle::FileLike, inode_handle::InodeHandle},
|
fs::{file_handle::FileLike, inode_handle::InodeHandle},
|
||||||
@ -62,12 +62,6 @@ impl FlockItem {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits until the lock can be acquired.
|
|
||||||
pub fn wait(&self) {
|
|
||||||
let cond = || None::<()>;
|
|
||||||
self.waitqueue.wait_until(cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wakes all threads that are waiting for this lock.
|
/// Wakes all threads that are waiting for this lock.
|
||||||
pub fn wake_all(&self) {
|
pub fn wake_all(&self) {
|
||||||
self.waitqueue.wake_all();
|
self.waitqueue.wake_all();
|
||||||
@ -102,14 +96,14 @@ impl Debug for FlockItem {
|
|||||||
/// Represents a list of non-POSIX file advisory locks (FLOCK).
|
/// Represents a list of non-POSIX file advisory locks (FLOCK).
|
||||||
/// The list is used to manage file locks and resolve conflicts between them.
|
/// The list is used to manage file locks and resolve conflicts between them.
|
||||||
pub struct FlockList {
|
pub struct FlockList {
|
||||||
inner: RwMutex<VecDeque<FlockItem>>,
|
inner: Mutex<VecDeque<FlockItem>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlockList {
|
impl FlockList {
|
||||||
/// Creates a new FlockList.
|
/// Creates a new FlockList.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: RwMutex::new(VecDeque::new()),
|
inner: Mutex::new(VecDeque::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,14 +117,15 @@ impl FlockList {
|
|||||||
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.lock();
|
||||||
if let Some(existing_lock) = list.iter().find(|l| req_lock.conflict_with(l)) {
|
if let Some(existing_lock) = list.iter().find(|l| req_lock.conflict_with(l)) {
|
||||||
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");
|
||||||
}
|
}
|
||||||
conflict_lock = existing_lock.clone();
|
(waiter, waker) = Waiter::new_pair();
|
||||||
|
existing_lock.waitqueue.enqueue(waker);
|
||||||
} else {
|
} else {
|
||||||
match list.iter().position(|l| req_lock.same_owner_with(l)) {
|
match list.iter().position(|l| req_lock.same_owner_with(l)) {
|
||||||
Some(idx) => {
|
Some(idx) => {
|
||||||
@ -143,7 +138,7 @@ impl FlockList {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conflict_lock.wait();
|
waiter.wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +152,7 @@ impl FlockList {
|
|||||||
"unlock with owner: {:?}",
|
"unlock with owner: {:?}",
|
||||||
req_owner as *const InodeHandle<R>
|
req_owner as *const InodeHandle<R>
|
||||||
);
|
);
|
||||||
let mut list = self.inner.write();
|
let mut list = self.inner.lock();
|
||||||
list.retain(|lock| {
|
list.retain(|lock| {
|
||||||
if let Some(owner) = lock.owner() {
|
if let Some(owner) = lock.owner() {
|
||||||
if ptr::eq(
|
if ptr::eq(
|
||||||
|
Reference in New Issue
Block a user