autocommit 2022-04-10 18:26:13 CEST
This commit is contained in:
parent
af152f7f3e
commit
6b3316e920
26 changed files with 514 additions and 82 deletions
|
|
@ -3,11 +3,12 @@ pub use {
|
|||
fd::{AsyncFd, FdStatus},
|
||||
task::SpawnedFuture,
|
||||
timeout::Timeout,
|
||||
timer::Timer,
|
||||
};
|
||||
use {
|
||||
crate::{
|
||||
event_loop::{EventLoop, EventLoopError},
|
||||
utils::{copyhashmap::CopyHashMap, numcell::NumCell},
|
||||
utils::{copyhashmap::CopyHashMap, numcell::NumCell, oserror::OsError},
|
||||
wheel::{Wheel, WheelError},
|
||||
},
|
||||
fd::AsyncFdData,
|
||||
|
|
@ -19,15 +20,21 @@ use {
|
|||
},
|
||||
thiserror::Error,
|
||||
timeout::TimeoutData,
|
||||
uapi::OwnedFd,
|
||||
uapi::{c, OwnedFd},
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AsyncError {
|
||||
#[error("The timer wheel returned an error: {0}")]
|
||||
#[error("The timer wheel returned an error")]
|
||||
WheelError(#[from] WheelError),
|
||||
#[error("The event loop caused an error: {0}")]
|
||||
#[error("The event loop caused an error")]
|
||||
EventLoopError(#[from] EventLoopError),
|
||||
#[error("Could not read from a timer")]
|
||||
TimerReadError(#[source] OsError),
|
||||
#[error("Could not set a timer")]
|
||||
SetTimer(#[source] OsError),
|
||||
#[error("Could not create a timer")]
|
||||
CreateTimer(#[source] OsError),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
|
|
@ -71,6 +78,10 @@ impl AsyncEngine {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn timer(self: &Rc<Self>, clock_id: c::c_int) -> Result<Timer, AsyncError> {
|
||||
Timer::new(self, clock_id)
|
||||
}
|
||||
|
||||
pub fn spawn<T, F: Future<Output = T> + 'static>(&self, f: F) -> SpawnedFuture<T> {
|
||||
self.queue.spawn(Phase::EventHandling, f)
|
||||
}
|
||||
|
|
@ -146,6 +157,59 @@ mod yield_ {
|
|||
}
|
||||
}
|
||||
|
||||
mod timer {
|
||||
use {
|
||||
crate::async_engine::{AsyncEngine, AsyncError, AsyncFd},
|
||||
std::{rc::Rc, time::Duration},
|
||||
uapi::c,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Timer {
|
||||
fd: AsyncFd,
|
||||
}
|
||||
|
||||
impl Timer {
|
||||
pub(super) fn new(eng: &Rc<AsyncEngine>, clock_id: c::c_int) -> Result<Self, AsyncError> {
|
||||
let fd = match uapi::timerfd_create(clock_id, c::TFD_CLOEXEC | c::TFD_NONBLOCK) {
|
||||
Ok(fd) => fd,
|
||||
Err(e) => return Err(AsyncError::CreateTimer(e.into())),
|
||||
};
|
||||
let afd = eng.fd(&Rc::new(fd))?;
|
||||
Ok(Self { fd: afd })
|
||||
}
|
||||
|
||||
pub async fn expired(&self) -> Result<u64, AsyncError> {
|
||||
self.fd.readable().await?;
|
||||
let mut buf = 0u64;
|
||||
if let Err(e) = uapi::read(self.fd.raw(), &mut buf) {
|
||||
return Err(AsyncError::TimerReadError(e.into()));
|
||||
}
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
pub fn program(
|
||||
&self,
|
||||
initial: Option<Duration>,
|
||||
periodic: Option<Duration>,
|
||||
) -> Result<(), AsyncError> {
|
||||
let mut timerspec: c::itimerspec = uapi::pod_zeroed();
|
||||
if let Some(init) = initial {
|
||||
timerspec.it_value.tv_sec = init.as_secs() as _;
|
||||
timerspec.it_value.tv_nsec = init.subsec_nanos() as _;
|
||||
if let Some(per) = periodic {
|
||||
timerspec.it_interval.tv_sec = per.as_secs() as _;
|
||||
timerspec.it_interval.tv_nsec = per.subsec_nanos() as _;
|
||||
}
|
||||
}
|
||||
if let Err(e) = uapi::timerfd_settime(self.fd.raw(), 0, &timerspec) {
|
||||
return Err(AsyncError::SetTimer(e.into()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod timeout {
|
||||
use {
|
||||
crate::wheel::{Wheel, WheelDispatcher, WheelId},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue