nuclei/sync/cancellation/
wait.rs1#![allow(unsafe_code)]
5
6use core::fmt;
7use core::future::Future;
8use core::mem::MaybeUninit;
9use core::pin::Pin;
10use core::task::{Context, Poll};
11
12use super::CancellationToken;
13use crate::sync::event::{Event, EventWait};
14
15pub(super) struct RunUntilCancelled<'a, F: Future> {
17 pub(super) cancellation: WaitForCancellationFuture<'a>,
18 pub(super) future: F,
19}
20
21impl<F: Future> Future for RunUntilCancelled<'_, F> {
22 type Output = Option<F::Output>;
23
24 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
25 let this = unsafe { self.get_unchecked_mut() };
29 let future = unsafe { Pin::new_unchecked(&mut this.future) };
31 if let Poll::Ready(output) = future.poll(cx) {
32 Poll::Ready(Some(output))
33 } else if Pin::new(&mut this.cancellation).poll(cx).is_ready() {
34 Poll::Ready(None)
35 } else {
36 Poll::Pending
37 }
38 }
39}
40
41#[must_use = "futures do nothing unless polled"]
46pub struct WaitForCancellationFuture<'a> {
47 pub(super) wait: EventWait<'a>,
48}
49
50impl fmt::Debug for WaitForCancellationFuture<'_> {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 f.debug_struct("WaitForCancellationFuture").finish()
53 }
54}
55
56impl Future for WaitForCancellationFuture<'_> {
57 type Output = ();
58
59 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
60 Pin::new(&mut self.get_mut().wait).poll(cx)
61 }
62}
63
64#[repr(transparent)]
69struct MaybeDangling<T>(MaybeUninit<T>);
70
71impl<T> MaybeDangling<T> {
72 fn new(inner: T) -> Self {
73 Self(MaybeUninit::new(inner))
74 }
75
76 fn get_mut(&mut self) -> &mut T {
77 unsafe { self.0.assume_init_mut() }
79 }
80}
81
82impl<T> Drop for MaybeDangling<T> {
83 fn drop(&mut self) {
84 unsafe { self.0.assume_init_drop() };
86 }
87}
88
89#[must_use = "futures do nothing unless polled"]
94pub struct WaitForCancellationFutureOwned {
95 wait: MaybeDangling<EventWait<'static>>,
99 _token: CancellationToken,
100}
101
102impl WaitForCancellationFutureOwned {
103 pub(super) fn new(token: CancellationToken) -> Self {
104 let event: *const Event = &token.node.cancelled;
105 let wait = unsafe { (*event).wait() };
109 Self {
110 wait: MaybeDangling::new(wait),
111 _token: token,
112 }
113 }
114}
115
116impl fmt::Debug for WaitForCancellationFutureOwned {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 f.debug_struct("WaitForCancellationFutureOwned").finish()
119 }
120}
121
122impl Future for WaitForCancellationFutureOwned {
123 type Output = ();
124
125 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
126 Pin::new(self.get_mut().wait.get_mut()).poll(cx)
127 }
128}