Add ordered lock for WaitQueue mutex without solving borrow check

This commit is contained in:
Wildan M
2026-03-11 09:24:45 +07:00
parent 60573e24f3
commit f07725682f
5 changed files with 14 additions and 15 deletions
+2 -2
View File
@@ -34,8 +34,8 @@ impl EventQueue {
}
}
pub fn is_currently_empty(&self) -> bool {
self.queue.is_currently_empty()
pub fn is_currently_empty(&self, token: &mut CleanLockToken) -> bool {
self.queue.is_currently_empty(token)
}
pub fn read(&self, buf: UserSliceWo, block: bool, token: &mut CleanLockToken) -> Result<usize> {
+1 -1
View File
@@ -122,7 +122,7 @@ impl KernelScheme for EventScheme {
// It is always possible to write events
ready |= EventFlags::EVENT_WRITE;
}
if flags.contains(EventFlags::EVENT_READ) && !queue.is_currently_empty() {
if flags.contains(EventFlags::EVENT_READ) && !queue.is_currently_empty(token) {
// It is possible to read if queue is not empty
ready |= EventFlags::EVENT_READ;
}
+1 -1
View File
@@ -312,7 +312,7 @@ impl KernelScheme for SchemeList {
token: &mut CleanLockToken,
) -> Result<EventFlags> {
match self.get_user_inner(id, token) {
Some(inner) => inner.fevent(flags),
Some(inner) => inner.fevent(flags, token),
_ => Err(Error::new(EBADF)),
}
}
+2 -2
View File
@@ -973,10 +973,10 @@ impl UserInner {
Ok(())
}
pub fn fevent(&self, flags: EventFlags) -> Result<EventFlags> {
pub fn fevent(&self, flags: EventFlags, token: &mut CleanLockToken) -> Result<EventFlags> {
// TODO: Should the root scheme also suppress events if `flags` does not contain
// `EVENT_READ`?
Ok(if self.todo.is_currently_empty() {
Ok(if self.todo.is_currently_empty(token) {
EventFlags::empty()
} else {
EventFlags::EVENT_READ.intersection(flags)
+8 -9
View File
@@ -1,9 +1,8 @@
use alloc::collections::VecDeque;
use spin::Mutex;
use syscall::{EAGAIN, EINTR};
use crate::{
sync::{CleanLockToken, LockToken, WaitCondition, L1},
sync::{CleanLockToken, LockToken, Mutex, WaitCondition, L1},
syscall::{
error::{Error, Result, EINVAL},
usercopy::UserSliceWo,
@@ -12,7 +11,7 @@ use crate::{
#[derive(Debug)]
pub struct WaitQueue<T> {
pub inner: Mutex<VecDeque<T>>,
inner: Mutex<L1, VecDeque<T>>,
pub condition: WaitCondition,
}
@@ -23,8 +22,8 @@ impl<T> WaitQueue<T> {
condition: WaitCondition::new(),
}
}
pub fn is_currently_empty(&self) -> bool {
self.inner.lock().is_empty()
pub fn is_currently_empty(&self, token: &mut CleanLockToken) -> bool {
self.inner.lock(token.token()).is_empty()
}
pub fn receive_into_user(
&self,
@@ -34,8 +33,8 @@ impl<T> WaitQueue<T> {
token: &mut CleanLockToken,
) -> Result<usize> {
loop {
let mut inner = self.inner.lock();
let mut token = token.downgrade();
let inner = self.inner.lock(token.token());
let (mut inner, mut token) = inner.into_split();
if inner.is_empty() {
if block {
@@ -77,9 +76,9 @@ impl<T> WaitQueue<T> {
self.send_locked(value, token.token().downgrade())
}
pub fn send_locked(&self, value: T, token: LockToken<'_, L1>) -> usize {
pub fn send_locked(&self, value: T, mut token: LockToken<'_, L1>) -> usize {
let len = {
let mut inner = self.inner.lock();
let mut inner = self.inner.lock(token.token());
inner.push_back(value);
inner.len()
};