#[ allow(unused_imports) ]
use
{
futures_util :: { future::{ FutureExt, abortable }, task::SpawnExt } ,
futures_task :: { SpawnError, FutureObj } ,
crate :: { import::*, JoinHandle, remote_handle::remote_handle } ,
std :: { pin::Pin, future::Future, sync::{ Arc, atomic::AtomicBool }, rc::Rc } ,
};
#[ cfg_attr( nightly, doc(cfg( feature = "spawn_handle" )) ) ]
pub trait SpawnHandle<Out: 'static + Send>
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>;
}
#[ cfg_attr( nightly, doc(cfg( feature = "spawn_handle" )) ) ]
pub trait SpawnHandleExt<Out: 'static + Send> : SpawnHandle<Out>
{
fn spawn_handle( &self, future: impl Future<Output = Out> + Send + 'static ) -> Result<JoinHandle<Out>, SpawnError>;
}
impl<T, Out> SpawnHandleExt<Out> for T
where T : SpawnHandle<Out> + ?Sized ,
Out: 'static + Send ,
{
fn spawn_handle( &self, future: impl Future<Output = Out> + Send + 'static ) -> Result<JoinHandle<Out>, SpawnError>
{
self.spawn_handle_obj( FutureObj::new(future.boxed()) )
}
}
impl<T: ?Sized, Out> SpawnHandle<Out> for Box<T> where T: SpawnHandle<Out>, Out: 'static + Send
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
(**self).spawn_handle_obj( future )
}
}
impl<T: ?Sized, Out> SpawnHandle<Out> for Arc<T> where T: SpawnHandle<Out>, Out: 'static + Send
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
(**self).spawn_handle_obj( future )
}
}
impl<T: ?Sized, Out> SpawnHandle<Out> for Rc<T> where T: SpawnHandle<Out>, Out: 'static + Send
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
(**self).spawn_handle_obj( future )
}
}
impl<T, Out> SpawnHandle<Out> for &T where T: SpawnHandle<Out>, Out: 'static + Send
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
(**self).spawn_handle_obj( future )
}
}
impl<T, Out> SpawnHandle<Out> for &mut T where T: SpawnHandle<Out>, Out: 'static + Send
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
(**self).spawn_handle_obj( future )
}
}
#[ cfg( feature = "tracing" ) ]
impl<T, Out> SpawnHandle<Out> for Instrumented<T> where T: SpawnHandle<Out>, Out: 'static + Send
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let fut = future.instrument( self.span().clone() );
self.inner().spawn_handle_obj( FutureObj::new(fut.boxed()) )
}
}
#[ cfg( feature = "tracing" ) ]
impl<T, Out> SpawnHandle<Out> for WithDispatch<T> where T: SpawnHandle<Out>, Out: 'static + Send
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let fut = self.with_dispatch( future );
self.inner().spawn_handle_obj( FutureObj::new(fut.boxed()) )
}
}
#[ cfg( feature = "async_std" ) ]
impl<Out: 'static + Send> SpawnHandle<Out> for crate::async_std::AsyncStd
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let (fut, a_handle) = abortable( future );
Ok( JoinHandle{ inner: crate::join_handle::InnerJh::AsyncStd
{
handle : async_std_crate::task::spawn( fut ) ,
detached: AtomicBool::new( false ) ,
a_handle ,
}})
}
}
#[ cfg(any( feature = "tokio_tp", feature = "tokio_ct" )) ]
impl<Out: 'static + Send> SpawnHandle<Out> for crate::TokioHandle
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let (fut, a_handle) = abortable( future );
Ok( JoinHandle{ inner: crate::join_handle::InnerJh::Tokio
{
handle : self.spawner.spawn( fut ) ,
detached: AtomicBool::new( false ) ,
a_handle ,
}})
}
}
#[ cfg( feature = "tokio_tp" ) ]
impl<Out: 'static + Send> SpawnHandle<Out> for crate::TokioTp
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let (fut, a_handle) = abortable( future );
Ok( JoinHandle{ inner: crate::join_handle::InnerJh::Tokio
{
handle : self.handle.spawn( fut ) ,
detached: AtomicBool::new( false ) ,
a_handle ,
}})
}
}
#[ cfg( feature = "tokio_ct" ) ]
impl<Out: 'static + Send> SpawnHandle<Out> for crate::TokioCt
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let (fut, a_handle) = abortable( future );
Ok( JoinHandle{ inner: crate::join_handle::InnerJh::Tokio
{
handle : self.handle.spawn( fut ) ,
detached: AtomicBool::new( false ) ,
a_handle ,
}})
}
}
#[ cfg( feature = "bindgen" ) ]
impl<Out: 'static + Send> SpawnHandle<Out> for crate::Bindgen
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let (fut, handle) = remote_handle( future );
wasm_bindgen_futures::spawn_local(fut);
Ok( JoinHandle{ inner: crate::join_handle::InnerJh::RemoteHandle( Some(handle) ) } )
}
}
#[ cfg( feature = "localpool" ) ]
impl<Out: 'static + Send> SpawnHandle<Out> for futures_executor::LocalSpawner
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let (fut, handle) = remote_handle( future );
self.spawn( fut )?;
Ok( JoinHandle{ inner: crate::join_handle::InnerJh::RemoteHandle( Some(handle) ) } )
}
}
#[ cfg( feature = "threadpool" ) ]
impl<Out: 'static + Send> SpawnHandle<Out> for futures_executor::ThreadPool
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let (fut, handle) = remote_handle( future );
self.spawn( fut )?;
Ok( JoinHandle{ inner: crate::join_handle::InnerJh::RemoteHandle( Some(handle) ) } )
}
}