use core::{
fmt,
future::Future,
marker::PhantomData,
mem,
pin::Pin,
task::{Context, Poll},
};
/// A custom trait object for polling futures, roughly akin to /// `Box<dyn Future<Output = T> + 'a>`. /// /// This custom trait object was introduced as currently it is not possible to /// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std /// contexts. pubstruct LocalFutureObj<'a, T> {
future: *mut (dyn Future<Output = T> + 'static),
drop_fn: unsafefn(*mut (dyn Future<Output = T> + 'static)),
_marker: PhantomData<&'a ()>,
}
// As LocalFutureObj only holds pointers, even if we move it, the pointed to values won't move, // so this is safe as long as we don't provide any way for a user to directly access the pointers // and move their values. impl<T> Unpin for LocalFutureObj<'_, T> {}
/// Converts the `LocalFutureObj` into a `FutureObj`. /// /// # Safety /// /// To make this operation safe one has to ensure that the `UnsafeFutureObj` /// instance from which this `LocalFutureObj` was created actually /// implements `Send`. #[inline] pubunsafefn into_future_obj(self) -> FutureObj<'a, T> {
FutureObj(self)
}
}
impl<T> Drop for LocalFutureObj<'_, T> { fn drop(&mutself) { unsafe { (self.drop_fn)(self.future) }
}
}
/// A custom trait object for polling futures, roughly akin to /// `Box<dyn Future<Output = T> + Send + 'a>`. /// /// This custom trait object was introduced as currently it is not possible to /// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std /// contexts. /// /// You should generally not need to use this type outside of `no_std` or when /// implementing `Spawn`, consider using `BoxFuture` instead. pubstruct FutureObj<'a, T>(LocalFutureObj<'a, T>);
impl<T> Unpin for FutureObj<'_, T> {} unsafeimpl<T> Send for FutureObj<'_, T> {}
impl<'a, T> FutureObj<'a, T> { /// Create a `FutureObj` from a custom trait object representation. #[inline] pubfn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> Self { Self(LocalFutureObj::new(f))
}
}
/// A custom implementation of a future trait object for `FutureObj`, providing /// a vtable with drop support. /// /// This custom representation is typically used only in `no_std` contexts, /// where the default `Box`-based implementation is not available. /// /// # Safety /// /// See the safety notes on individual methods for what guarantees an /// implementor must provide. pubunsafetrait UnsafeFutureObj<'a, T>: 'a { /// Convert an owned instance into a (conceptually owned) fat pointer. /// /// # Safety /// /// ## Implementor /// /// The trait implementor must guarantee that it is safe to convert the /// provided `*mut (dyn Future<Output = T> + 'a)` into a `Pin<&mut (dyn /// Future<Output = T> + 'a)>` and call methods on it, non-reentrantly, /// until `UnsafeFutureObj::drop` is called with it. #[allow(clippy::unnecessary_safety_doc)] fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a);
/// Drops the future represented by the given fat pointer. /// /// # Safety /// /// ## Implementor /// /// The trait implementor must guarantee that it is safe to call this /// function once per `into_raw` invocation. /// /// ## Caller /// /// The caller must ensure: /// /// * the pointer passed was obtained from an `into_raw` invocation from /// this same trait object /// * the pointer is not currently in use as a `Pin<&mut (dyn Future<Output /// = T> + 'a)>` /// * the pointer must not be used again after this function is called unsafefn drop(ptr: *mut (dyn Future<Output = T> + 'a));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.