/// Allows spawning non-`static futures on the thread pool. The function takes a callback,
/// passing a scope object into it. The scope object provided to the callback can be used
/// to spawn tasks. This function will await the completion of all tasks before returning.
///
/// This is similar to `rayon::scope` and `crossbeam::scope`
Allows spawning non-`static futures on the thread pool. The function takes a callback,
passing a scope object into it. The scope object provided to the callback can be used
to spawn tasks. This function will await the completion of all tasks before returning.

This is similar to `rayon::scope` and `crossbeam::scope`
Allows spawning non - ` static futures on the thread pool . The function takes a callback passing a scope object into it . The scope object provided to the callback can be used to spawn tasks . This function will await the completion of all tasks before returning . This is similar to ` rayon :: scope ` and ` crossbeam :: scope `
pub fn scope<'scope, F, T>(&self, f: F) -> Vec<T>
    where
        F: FnOnce(&mut Scope<'scope, T>) + 'scope + Send,
        T: Send + 'static,
    {
        // SAFETY: This function blocks until all futures complete, so this future must return
        // before this function returns. However, rust has no way of knowing
        // this so we must convert to 'static here to appease the compiler as it is unable to
        // validate safety.
        let executor: &async_executor::Executor = &*self.executor;
        let executor: &'scope async_executor::Executor = unsafe { mem::transmute(executor) };
        let mut scope = Scope {
            executor,
            spawned: Vec::new(),
        };
        f(&mut scope);
        if scope.spawned.is_empty() {
            Vec::default()
        } else if scope.spawned.len() == 1 {
            vec![future::block_on(&mut scope.spawned[0])]
        } else {
            let fut = async move {
                let mut results = Vec::with_capacity(scope.spawned.len());
                for task in scope.spawned {
                    results.push(task.await);
                }
                results
            };
            // Pin the future on the stack.
            pin!(fut);
            // SAFETY: This function blocks until all futures complete, so we do not read/write the
            // data from futures outside of the 'scope lifetime. However, rust has no way of knowing
            // this so we must convert to 'static here to appease the compiler as it is unable to
            // validate safety.
            let fut: Pin<&mut (dyn Future<Output = Vec<T>> + Send)> = fut;
            let fut: Pin<&'static mut (dyn Future<Output = Vec<T>> + Send + 'static)> =
                unsafe { mem::transmute(fut) };
            // The thread that calls scope() will participate in driving tasks in the pool forward
            // until the tasks that are spawned by this scope() call complete. (If the caller of scope()
            // happens to be a thread in this thread pool, and we only have one thread in the pool, then
            // simply calling future::block_on(spawned) would deadlock.)
            let mut spawned = self.executor.spawn(fut);
            loop {
                if let Some(result) = future::block_on(future::poll_once(&mut spawned)) {
                    break result;
                }
                self.executor.try_tick();
            }
        }
    }
pub fn scope < ' scope , F , T > ( & self , f : F ) -> Vec < T > where F : FnOnce ( & mut Scope < ' scope , T > ) + ' scope + Send , T : Send + ' static , { // SAFETY: This function blocks until all futures complete, so this future must return // before this function returns. However, rust has no way of knowing // this so we must convert to 'static here to appease the compiler as it is unable to // validate safety. let executor : & async_executor :: Executor = & * self . executor ; let executor : & ' scope async_executor :: Executor = unsafe { mem :: transmute ( executor ) } ; let mut scope = Scope { executor , spawned : Vec :: new ( ) , } ; f ( & mut scope ) ; if scope . spawned . is_empty ( ) { Vec :: default ( ) } else if scope . spawned . len ( ) == 1 { vec ! [ future block_on ( mut scope spawned [ 0 ] ) ] } else { let fut = async move { let mut results = Vec :: with_capacity ( scope . spawned . len ( ) ) ; for task in scope . spawned { results . push ( task . await ) ; } results } ; // Pin the future on the stack. pin ! ( fut ) ; // SAFETY: This function blocks until all futures complete, so we do not read/write the // data from futures outside of the 'scope lifetime. However, rust has no way of knowing // this so we must convert to 'static here to appease the compiler as it is unable to // validate safety. let fut : Pin < & mut ( dyn Future < Output = Vec < T > > + Send ) > = fut ; let fut : Pin < & ' static mut ( dyn Future < Output = Vec < T > > + Send + ' static ) > = unsafe { mem :: transmute ( fut ) } ; // The thread that calls scope() will participate in driving tasks in the pool forward // until the tasks that are spawned by this scope() call complete. (If the caller of scope() // happens to be a thread in this thread pool, and we only have one thread in the pool, then // simply calling future::block_on(spawned) would deadlock.) let mut spawned = self . executor . spawn ( fut ) ; loop { if let Some ( result ) = future :: block_on ( future :: poll_once ( & mut spawned ) ) { break result ; } self . executor . try_tick ( ) ; } } }
Allows spawning non-`static futures on the thread pool.
Allows spawning non - ` static futures on the thread pool .
&self
f
F