mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-25 02:13:24 +00:00
Make *_or_timeout
APIs concise
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
10cc85d588
commit
32b8e05cc3
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use core::{sync::atomic::Ordering, time::Duration};
|
||||
use core::sync::atomic::Ordering;
|
||||
|
||||
use ostd::sync::{WaitQueue, Waiter};
|
||||
|
||||
@ -9,7 +9,7 @@ use crate::{
|
||||
prelude::*,
|
||||
process::posix_thread::PosixThreadExt,
|
||||
thread::Thread,
|
||||
time::wait::{TimerBuilder, WaitTimeout},
|
||||
time::wait::{ManagedTimeout, TimeoutExt},
|
||||
};
|
||||
|
||||
/// `Pause` is an extension trait to make [`Waiter`] and [`WaitQueue`] signal aware.
|
||||
@ -36,7 +36,7 @@ pub trait Pause: WaitTimeout {
|
||||
where
|
||||
F: FnMut() -> Option<R>,
|
||||
{
|
||||
self.pause_until_or_timer_timeout_opt(cond, None)
|
||||
self.pause_until_or_timeout_impl(cond, None)
|
||||
}
|
||||
|
||||
/// Pauses the execution of the current thread until the `cond` is met ( i.e., `cond()`
|
||||
@ -51,26 +51,18 @@ pub trait Pause: WaitTimeout {
|
||||
///
|
||||
/// [`ETIME`]: crate::error::Errno::ETIME
|
||||
/// [`EINTR`]: crate::error::Errno::EINTR
|
||||
fn pause_until_or_timeout<F, R>(&self, mut cond: F, timeout: &Duration) -> Result<R>
|
||||
fn pause_until_or_timeout<'a, F, T, R>(&self, mut cond: F, timeout: T) -> Result<R>
|
||||
where
|
||||
F: FnMut() -> Option<R>,
|
||||
T: Into<TimeoutExt<'a>>,
|
||||
{
|
||||
if *timeout == Duration::ZERO {
|
||||
return cond()
|
||||
.ok_or_else(|| Error::with_message(Errno::ETIME, "the time limit is reached"));
|
||||
}
|
||||
let timer_builder = TimerBuilder::new(timeout);
|
||||
self.pause_until_or_timer_timeout_opt(cond, Some(&timer_builder))
|
||||
}
|
||||
let timeout = timeout.into();
|
||||
let timeout_inner = match timeout.check_expired() {
|
||||
Ok(inner) => inner,
|
||||
Err(err) => return cond().ok_or(err),
|
||||
};
|
||||
|
||||
/// Similar to [`Pause::pause_until_or_timeout`].
|
||||
///
|
||||
/// The only difference is that the timeout is against the user-specified clock.
|
||||
fn pause_until_or_timer_timeout<F, R>(&self, cond: F, timer_builder: &TimerBuilder) -> Result<R>
|
||||
where
|
||||
F: FnMut() -> Option<R>,
|
||||
{
|
||||
self.pause_until_or_timer_timeout_opt(cond, Some(timer_builder))
|
||||
self.pause_until_or_timeout_impl(cond, timeout_inner)
|
||||
}
|
||||
|
||||
/// Pauses the execution of the current thread until the `cond` is met ( i.e., `cond()`
|
||||
@ -85,10 +77,11 @@ pub trait Pause: WaitTimeout {
|
||||
///
|
||||
/// [`ETIME`]: crate::error::Errno::ETIME
|
||||
/// [`EINTR`]: crate::error::Errno::EINTR
|
||||
fn pause_until_or_timer_timeout_opt<F, R>(
|
||||
#[doc(hidden)]
|
||||
fn pause_until_or_timeout_impl<F, R>(
|
||||
&self,
|
||||
cond: F,
|
||||
timer_builder: Option<&TimerBuilder>,
|
||||
timeout: Option<&ManagedTimeout>,
|
||||
) -> Result<R>
|
||||
where
|
||||
F: FnMut() -> Option<R>;
|
||||
@ -101,21 +94,20 @@ pub trait Pause: WaitTimeout {
|
||||
///
|
||||
/// If `timeout` is expired before woken up or some signals are received,
|
||||
/// this method will return [`Errno::ETIME`].
|
||||
fn pause_timer_timeout(&self, timer_builder: Option<&TimerBuilder>) -> Result<()>;
|
||||
fn pause_timeout<'a>(&self, timeout: impl Into<TimeoutExt<'a>>) -> Result<()>;
|
||||
}
|
||||
|
||||
impl Pause for Waiter {
|
||||
fn pause_until_or_timer_timeout_opt<F, R>(
|
||||
fn pause_until_or_timeout_impl<F, R>(
|
||||
&self,
|
||||
mut cond: F,
|
||||
timer_builder: Option<&TimerBuilder>,
|
||||
cond: F,
|
||||
timeout: Option<&ManagedTimeout>,
|
||||
) -> Result<R>
|
||||
where
|
||||
F: FnMut() -> Option<R>,
|
||||
{
|
||||
if let Some(res) = cond() {
|
||||
return Ok(res);
|
||||
}
|
||||
// No fast paths for `Waiter`. If the caller wants a fast path, it should do so _before_
|
||||
// the waiter is created.
|
||||
|
||||
let current_thread = self.task().data().downcast_ref::<Arc<Thread>>();
|
||||
|
||||
@ -123,11 +115,7 @@ impl Pause for Waiter {
|
||||
.as_ref()
|
||||
.and_then(|thread| thread.as_posix_thread())
|
||||
else {
|
||||
if let Some(timer_builder) = timer_builder {
|
||||
return self.wait_until_or_timer_timeout(cond, timer_builder);
|
||||
} else {
|
||||
return self.wait_until_or_cancelled(cond, || Ok(()));
|
||||
}
|
||||
return self.wait_until_or_timeout_cancelled(cond, || Ok(()), timeout);
|
||||
};
|
||||
|
||||
let cancel_cond = || {
|
||||
@ -141,19 +129,16 @@ impl Pause for Waiter {
|
||||
};
|
||||
|
||||
posix_thread.set_signalled_waker(self.waker());
|
||||
let res = if let Some(timer_builder) = timer_builder {
|
||||
self.wait_until_or_timer_timeout_cancelled(cond, cancel_cond, timer_builder)
|
||||
} else {
|
||||
self.wait_until_or_cancelled(cond, cancel_cond)
|
||||
};
|
||||
let res = self.wait_until_or_timeout_cancelled(cond, cancel_cond, timeout);
|
||||
posix_thread.clear_signalled_waker();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn pause_timer_timeout(&self, timer_builder: Option<&TimerBuilder>) -> Result<()> {
|
||||
let timer = timer_builder.map(|timer_builder| {
|
||||
fn pause_timeout<'a>(&self, timeout: impl Into<TimeoutExt<'a>>) -> Result<()> {
|
||||
let timer = timeout.into().check_expired()?.map(|timeout| {
|
||||
let waker = self.waker();
|
||||
timer_builder.fire(move || {
|
||||
timeout.create_timer(move || {
|
||||
waker.wake_up();
|
||||
})
|
||||
});
|
||||
@ -184,14 +169,15 @@ impl Pause for Waiter {
|
||||
}
|
||||
|
||||
impl Pause for WaitQueue {
|
||||
fn pause_until_or_timer_timeout_opt<F, R>(
|
||||
fn pause_until_or_timeout_impl<F, R>(
|
||||
&self,
|
||||
mut cond: F,
|
||||
timer_builder: Option<&TimerBuilder>,
|
||||
timeout: Option<&ManagedTimeout>,
|
||||
) -> Result<R>
|
||||
where
|
||||
F: FnMut() -> Option<R>,
|
||||
{
|
||||
// Fast path:
|
||||
if let Some(res) = cond() {
|
||||
return Ok(res);
|
||||
}
|
||||
@ -201,11 +187,11 @@ impl Pause for WaitQueue {
|
||||
self.enqueue(waiter.waker());
|
||||
cond()
|
||||
};
|
||||
waiter.pause_until_or_timer_timeout_opt(cond, timer_builder)
|
||||
waiter.pause_until_or_timeout_impl(cond, timeout)
|
||||
}
|
||||
|
||||
fn pause_timer_timeout(&self, _timer_builder: Option<&TimerBuilder>) -> Result<()> {
|
||||
panic!("`pause_timer_timeout` can only be used on `Waiter`");
|
||||
fn pause_timeout<'a>(&self, _timeout: impl Into<TimeoutExt<'a>>) -> Result<()> {
|
||||
panic!("`pause_timeout` can only be used on `Waiter`");
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user