Next Generation WASM Microkernel Operating System
at trap_handler 108 lines 2.9 kB view raw
1// Copyright 2025. Jonas Kruckenberg 2// 3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5// http://opensource.org/licenses/MIT>, at your option. This file may not be 6// copied, modified, or distributed except according to those terms. 7 8use pin_project::pin_project; 9 10use crate::time::{ 11 TimeError, Timer, 12 instant::Instant, 13 sleep::{Sleep, sleep, sleep_until}, 14}; 15use core::{ 16 pin::Pin, 17 task::{Context, Poll}, 18 time::Duration, 19}; 20 21/// Requires a `Future` to complete before the specified duration has elapsed. 22/// 23/// # Errors 24/// 25/// This function fails for two reasons: 26/// 1. [`TimeError::NoGlobalTimer`] No global timer has been set up yet. Call [`crate::time::set_global_timer`] first. 27/// 2. [`TimeError::DurationTooLong`] The requested deadline lies too far into the future 28pub fn timeout<F>( 29 timer: &Timer, 30 duration: Duration, 31 future: F, 32) -> Result<Timeout<F::IntoFuture>, TimeError> 33where 34 F: IntoFuture, 35{ 36 Ok(Timeout { 37 sleep: sleep(timer, duration)?, 38 future: future.into_future(), 39 }) 40} 41 42/// Requires a `Future` to complete before the specified deadline has been reached. 43/// 44/// # Errors 45/// 46/// This function fails for two reasons: 47/// 1. [`TimeError::NoGlobalTimer`] No global timer has been set up yet. Call [`crate::time::set_global_timer`] first. 48/// 2. [`TimeError::DurationTooLong`] The requested deadline lies too far into the future 49pub fn timeout_at<F>( 50 timer: &Timer, 51 deadline: Instant, 52 future: F, 53) -> Result<Timeout<F::IntoFuture>, TimeError> 54where 55 F: IntoFuture, 56{ 57 Ok(Timeout { 58 sleep: sleep_until(timer, deadline)?, 59 future: future.into_future(), 60 }) 61} 62 63/// Future returned by [`timeout`] and [`timeout_at`]. 64#[pin_project] 65#[must_use = "futures do nothing unless `.await`ed or `poll`ed"] 66pub struct Timeout<'timer, F> { 67 #[pin] 68 sleep: Sleep<'timer>, 69 #[pin] 70 future: F, 71} 72 73#[derive(Debug)] 74pub struct Elapsed(()); 75 76impl<F> Timeout<'_, F> { 77 /// Gets a reference to the underlying future in this timeout. 78 pub fn get_ref(&self) -> &F { 79 &self.future 80 } 81 82 /// Consumes this timeout, returning the underlying future. 83 pub fn get_mut(&mut self) -> &mut F { 84 &mut self.future 85 } 86 87 /// Consumes this timeout, returning the underlying future. 88 pub fn into_inner(self) -> F { 89 self.future 90 } 91} 92 93impl<F: Future> Future for Timeout<'_, F> { 94 type Output = Result<F::Output, Elapsed>; 95 96 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 97 let me = self.project(); 98 99 if let Poll::Ready(v) = me.future.poll(cx) { 100 return Poll::Ready(Ok(v)); 101 } 102 103 match me.sleep.poll(cx) { 104 Poll::Ready(()) => Poll::Ready(Err(Elapsed(()))), 105 Poll::Pending => Poll::Pending, 106 } 107 } 108}