#[ allow(unused_imports) ] use
{
std :: { future::Future, sync::atomic::{ AtomicBool, Ordering } } ,
std :: { task::{ Poll, Context }, pin::Pin } ,
futures_util:: { future::{ AbortHandle, Aborted, RemoteHandle }, ready } ,
super :: *,
};
#[ cfg( feature = "async_global" ) ]
type BoxedFut<T> = Pin<Box< dyn Future<Output=T> + Send >>;
#[ derive( Debug ) ]
pub struct BlockingHandle<T>( InnerBh<T> );
impl<T> BlockingHandle<T>
{
#[ cfg(any( feature = "tokio_tp", feature = "tokio_ct" )) ]
pub fn tokio( handle: TokioJoinHandle<T> ) -> Self
{
Self( InnerBh::Tokio(handle) )
}
#[ cfg( feature = "async_global" ) ]
pub fn async_global( task: BoxedFut<T> ) -> Self
{
Self( InnerBh::AsyncGlobal(task) )
}
#[ cfg( feature = "async_std" ) ]
pub fn async_std( handle: AsyncStdJoinHandle<T> ) -> Self
{
Self( InnerBh::AsyncStd(handle) )
}
}
#[ allow(dead_code) ]
enum InnerBh<T>
{
#[ cfg(any( feature = "tokio_tp", feature = "tokio_ct" )) ]
Tokio( TokioJoinHandle<T> ),
#[ cfg( feature = "async_global" ) ]
AsyncGlobal( BoxedFut<T> ),
#[ cfg( feature = "async_std" ) ]
AsyncStd( AsyncStdJoinHandle<T> ),
Phantom( std::marker::PhantomData< fn()->T > ),
}
impl<T: 'static> Future for BlockingHandle<T>
{
type Output = T;
fn poll( self: Pin<&mut Self>, _cx: &mut Context<'_> ) -> Poll<Self::Output>
{
match &mut self.get_mut().0
{
#[ cfg(any( feature = "tokio_tp", feature = "tokio_ct" )) ]
InnerBh::Tokio(handle) =>
{
match ready!( Pin::new( handle ).poll( _cx ) )
{
Ok(t) => Poll::Ready( t ),
Err(e) => panic!( "Task has been canceled or has panicked. \
Are you dropping the executor to early? Error: {}", e ),
}
}
#[ cfg( feature = "async_std" ) ] InnerBh::AsyncStd ( handle ) => Pin::new( handle ).poll( _cx ) ,
#[ cfg( feature = "async_global" ) ] InnerBh::AsyncGlobal( task ) => Pin::new( task ).poll( _cx ) ,
InnerBh::Phantom(_) => unreachable!(),
}
}
}
impl<T> std::fmt::Debug for InnerBh<T>
{
fn fmt( &self, f: &mut std::fmt::Formatter<'_> ) -> std::fmt::Result
{
write!( f, "InnerBh" )
}
}