scope_lock/extended/
future.rs1use core::future::Future;
2use core::marker::PhantomData;
3use core::pin::Pin;
4use core::ptr;
5use core::task;
6
7use crate::Extender;
8use crate::extended::sync::Reference;
9use crate::pointer_like::PointerPinUnforgotten;
10use crate::pointer_like::erased_static::{fn_drop, fn_poll_unforgotten};
11
12impl<'scope, 'env> Extender<'scope, 'env> {
13 pub fn future<'extended, P, O>(
15 &'scope self,
16 f: P,
17 ) -> impl Future<Output = O> + Send + Sync + 'extended
18 where
19 'extended: 'scope,
20 P: PointerPinUnforgotten + Send + 'scope,
21 P::Pointee: Future<Output = O>,
22 O: Send + 'extended,
23 {
24 let reference_guard = unsafe { self.rc.acquire() };
25
26 struct Fut<T> {
27 inner: T,
28 _reference_guard: Reference,
30 }
31 unsafe impl<T> Send for Fut<T> {}
32 unsafe impl<T> Sync for Fut<T> {}
33 impl<T: Future> Future for Fut<T> {
34 type Output = T::Output;
35
36 fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
37 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner).poll(cx) }
38 }
39 }
40
41 Fut {
43 inner: unsafe { extend_future_unchecked(f) },
44 _reference_guard: reference_guard,
45 }
46 }
47}
48
49pub unsafe fn extend_future_unchecked<'a, F, O>(f: F) -> impl Future<Output = O> + 'a
50where
51 F: PointerPinUnforgotten,
52 F::Pointee: Future<Output = O>,
53 O: 'a,
54{
55 unsafe {
56 ErasedFuture {
57 ptr: ptr::NonNull::new_unchecked(f.into_ptr() as *mut ()),
58 poll: fn_poll_unforgotten::<F, O>(),
59 drop: fn_drop::<F>(),
60 _marker: PhantomData,
61 }
62 }
63}
64
65struct ErasedFuture<P, O, D: Fn(*mut ())> {
66 ptr: ptr::NonNull<()>,
67 drop: D,
68 poll: P,
69 _marker: PhantomData<fn() -> task::Poll<O>>,
70}
71
72impl<P, O, D: Fn(*mut ())> Future for ErasedFuture<P, O, D>
73where
74 P: Fn(*mut (), &mut task::Context<'_>) -> task::Poll<O>,
75{
76 type Output = O;
77
78 fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
79 (self.poll)(self.ptr.as_ptr(), cx)
80 }
81}
82
83impl<P, O, D: Fn(*mut ())> Drop for ErasedFuture<P, O, D> {
84 fn drop(&mut self) {
85 (self.drop)(self.ptr.as_ptr())
86 }
87}
88
89pub mod legacy {
90 use core::future::Future;
91 use core::pin::Pin;
92 use core::ptr;
93 use core::task;
94
95 #[doc(hidden)]
96 pub struct ExtendedFuture<O> {
97 pub(crate) func: ptr::NonNull<dyn Future<Output = O> + Send>,
99 }
100
101 impl<O> Future for ExtendedFuture<O> {
102 type Output = O;
103
104 fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
105 unsafe { Pin::new_unchecked(self.get_unchecked_mut().func.as_mut()) }.poll(cx)
106 }
107 }
108
109 unsafe impl<O> Send for ExtendedFuture<O> where O: Send {}
110}