scoped_async_spawn/
scope.rs

1use std::{future::Future, pin::Pin, task::Poll};
2
3use super::pointer::Pointer;
4use pin_project_lite::pin_project;
5use scoped_tls::scoped_thread_local;
6
7scoped_thread_local!(static UNFORGETTABLE_SCOPE: Pointer);
8pin_project! {
9    pub struct GiveUnforgettableScope<F: Future> {
10        #[pin] fut: F,
11    }
12}
13impl<F: Future> Future for GiveUnforgettableScope<F> {
14    type Output = F::Output;
15
16    fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
17        let fut_ref: &F = &self.as_ref().fut;
18        let fut_ptr = Pointer::new(fut_ref);
19        UNFORGETTABLE_SCOPE.set(&fut_ptr, || self.project().fut.poll(cx))
20    }
21}
22impl<F: Future + 'static> GiveUnforgettableScope<F> {
23    pub fn new_static(fut: F) -> Self {
24        unsafe { Self::new(fut) }
25    }
26}
27impl<F: Future> GiveUnforgettableScope<F> {
28    pub unsafe fn new(fut: F) -> Self {
29        Self { fut }
30    }
31}
32pub fn check_scope(here: Pointer) -> bool {
33    UNFORGETTABLE_SCOPE.is_set() && UNFORGETTABLE_SCOPE.with(|sc| sc.contains(here))
34}
35pub unsafe fn set_scope<R, F: FnOnce() -> R>(val: Pointer, f: F) -> R {
36    UNFORGETTABLE_SCOPE.set(&val, f)
37}