|
@@ -3,11 +3,10 @@ use core::{
|
|
|
num::NonZeroUsize,
|
|
|
pin::Pin,
|
|
|
task::{Context, Poll},
|
|
|
- time::Duration,
|
|
|
};
|
|
|
|
|
|
use solvent::{
|
|
|
- prelude::{PackIntrWait, Result, SerdeReg, Syscall, EPIPE, SIG_GENERIC},
|
|
|
+ prelude::{PackIntrWait, Result, SerdeReg, Syscall, ENOENT, EPIPE, SIG_GENERIC},
|
|
|
time::Instant,
|
|
|
};
|
|
|
use solvent_core::{sync::channel::oneshot, thread::Backoff};
|
|
@@ -48,23 +47,17 @@ impl Interrupt {
|
|
|
|
|
|
#[inline]
|
|
|
pub fn last_time(&self) -> Result<Instant> {
|
|
|
- self.inner.wait(Duration::ZERO)
|
|
|
+ self.inner.last_time()
|
|
|
}
|
|
|
|
|
|
#[inline]
|
|
|
- pub fn wait_until(&self, deadline: Instant) -> WaitUntil<'_> {
|
|
|
- WaitUntil {
|
|
|
+ pub fn wait_next(&self) -> WaitNext<'_> {
|
|
|
+ WaitNext {
|
|
|
intr: self,
|
|
|
- deadline,
|
|
|
result: None,
|
|
|
key: None,
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- #[inline]
|
|
|
- pub async fn wait_next(&self) -> Result<Instant> {
|
|
|
- self.wait_until(Instant::now()).await
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
unsafe impl PackedSyscall for (PackIntrWait, oneshot::Sender<Result<Instant>>) {
|
|
@@ -81,14 +74,13 @@ unsafe impl PackedSyscall for (PackIntrWait, oneshot::Sender<Result<Instant>>) {
|
|
|
}
|
|
|
|
|
|
#[must_use]
|
|
|
-pub struct WaitUntil<'a> {
|
|
|
+pub struct WaitNext<'a> {
|
|
|
intr: &'a Interrupt,
|
|
|
- deadline: Instant,
|
|
|
result: Option<oneshot::Receiver<Result<Instant>>>,
|
|
|
key: Option<usize>,
|
|
|
}
|
|
|
|
|
|
-impl Future for WaitUntil<'_> {
|
|
|
+impl Future for WaitNext<'_> {
|
|
|
type Output = Result<Instant>;
|
|
|
|
|
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
@@ -101,38 +93,30 @@ impl Future for WaitUntil<'_> {
|
|
|
return Poll::Pending;
|
|
|
}
|
|
|
|
|
|
- let mut last_time = self.intr.last_time()?;
|
|
|
- if self.deadline <= last_time {
|
|
|
- return Poll::Ready(Ok(last_time));
|
|
|
- }
|
|
|
-
|
|
|
let backoff = Backoff::new();
|
|
|
let (mut tx, rx) = oneshot();
|
|
|
self.result = Some(rx);
|
|
|
loop {
|
|
|
- let pack = if self.deadline > last_time {
|
|
|
- let pack = self.intr.inner.pack_wait(self.deadline - last_time)?;
|
|
|
- let res = self.intr.disp.poll_send(
|
|
|
- &self.intr.inner,
|
|
|
- true,
|
|
|
- SIG_GENERIC,
|
|
|
- (pack, tx),
|
|
|
- cx.waker(),
|
|
|
- );
|
|
|
- match res {
|
|
|
- Err((_, pack)) => pack,
|
|
|
- Ok(Err(err)) => panic!("poll send: {err:?}"),
|
|
|
- Ok(Ok(key)) => {
|
|
|
- self.key = Some(key);
|
|
|
- break Poll::Pending;
|
|
|
+ match self.intr.inner.last_time() {
|
|
|
+ Err(ENOENT) => {
|
|
|
+ match self.intr.disp.poll_send(
|
|
|
+ &self.intr.inner,
|
|
|
+ true,
|
|
|
+ SIG_GENERIC,
|
|
|
+ (self.intr.inner.pack_query()?, tx),
|
|
|
+ cx.waker(),
|
|
|
+ ) {
|
|
|
+ Err(pack) => tx = pack.1,
|
|
|
+ Ok(Err(err)) => panic!("poll send: {err:?}"),
|
|
|
+ Ok(Ok(key)) => {
|
|
|
+ self.key = Some(key);
|
|
|
+ return Poll::Pending;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- } else {
|
|
|
- break Poll::Ready(Ok(last_time));
|
|
|
- };
|
|
|
- tx = pack;
|
|
|
- backoff.snooze();
|
|
|
- last_time = self.intr.last_time()?;
|
|
|
+ res => return Poll::Ready(res),
|
|
|
+ }
|
|
|
+ backoff.snooze()
|
|
|
}
|
|
|
}
|
|
|
}
|