async_executors/iface/
blocking_handle.rs1#[ allow(unused_imports) ] use
4{
5 std :: { future::Future, sync::atomic::{ AtomicBool, Ordering } } ,
6 std :: { task::{ Poll, Context }, pin::Pin } ,
7 futures_util:: { future::{ AbortHandle, Aborted, RemoteHandle }, ready } ,
8 super :: *,
9};
10
11
12#[ cfg( feature = "async_global" ) ]
13type BoxedFut<T> = Pin<Box< dyn Future<Output=T> + Send >>;
15
16
17#[ derive( Debug ) ]
23pub struct BlockingHandle<T>( InnerBh<T> );
25
26
27impl<T> BlockingHandle<T>
28{
29 #[ cfg(any( feature = "tokio_tp", feature = "tokio_ct" )) ]
32 pub fn tokio( handle: TokioJoinHandle<T> ) -> Self
34 {
35 Self( InnerBh::Tokio(handle) )
36 }
37
38
39 #[ cfg( feature = "async_global" ) ]
42 pub fn async_global( task: BoxedFut<T> ) -> Self
44 {
45 Self( InnerBh::AsyncGlobal(task) )
46 }
47
48
49 #[ cfg( feature = "async_std" ) ]
52 pub fn async_std( handle: AsyncStdJoinHandle<T> ) -> Self
54 {
55 Self( InnerBh::AsyncStd(handle) )
56 }
57}
58
59
60
61#[ allow(dead_code) ]
62enum InnerBh<T>
64{
65 #[ cfg(any( feature = "tokio_tp", feature = "tokio_ct" )) ]
68 Tokio( TokioJoinHandle<T> ),
70
71 #[ cfg( feature = "async_global" ) ]
74 AsyncGlobal( BoxedFut<T> ),
76
77 #[ cfg( feature = "async_std" ) ]
80 AsyncStd( AsyncStdJoinHandle<T> ),
82
83 Phantom( std::marker::PhantomData< fn()->T > ),
87}
88
89
90
91impl<T: 'static> Future for BlockingHandle<T>
92{
93 type Output = T;
94
95 fn poll( self: Pin<&mut Self>, _cx: &mut Context<'_> ) -> Poll<Self::Output>
96 {
97 match &mut self.get_mut().0
98 {
99 #[ cfg(any( feature = "tokio_tp", feature = "tokio_ct" )) ]
100 InnerBh::Tokio(handle) =>
102 {
103 match ready!( Pin::new( handle ).poll( _cx ) )
104 {
105 Ok(t) => Poll::Ready( t ),
106
107 Err(e) => panic!( "Task has been canceled or has panicked. \
108 Are you dropping the executor to early? Error: {}", e ),
109 }
110 }
111
112 #[ cfg( feature = "async_std" ) ] InnerBh::AsyncStd ( handle ) => Pin::new( handle ).poll( _cx ) ,
113 #[ cfg( feature = "async_global" ) ] InnerBh::AsyncGlobal( task ) => Pin::new( task ).poll( _cx ) ,
114
115 InnerBh::Phantom(_) => unreachable!(),
116 }
117 }
118}
119
120
121
122impl<T> std::fmt::Debug for InnerBh<T>
123{
124 fn fmt( &self, f: &mut std::fmt::Formatter<'_> ) -> std::fmt::Result
125 {
126 write!( f, "InnerBh" )
127 }
128}