Skip to main content

async_executors/exec/
async_std.rs

1use
2{
3	crate        :: { SpawnHandle, LocalSpawnHandle, JoinHandle,               } ,
4	futures_task :: { FutureObj, LocalFutureObj, Spawn, LocalSpawn, SpawnError } ,
5	futures_util :: { future::abortable                                        } ,
6
7	async_std_crate as async_std,
8};
9
10
11/// An executor that spawns tasks on async-std. In contrast to the other executors, this one
12/// is not self contained, because async-std does not provide an API that allows that,
13/// so the threadpool is global.
14///
15/// It works on Wasm.
16//
17#[ derive( Copy, Clone, Default ) ]
18//
19#[ cfg_attr( nightly, doc(cfg( feature = "async_std" )) ) ]
20//
21pub struct AsyncStd;
22
23impl AsyncStd
24{
25	/// Create a new AsyncStd wrapper.
26	///
27	pub fn new() -> Self
28	{
29		Self
30	}
31
32
33	/// Wrapper around [async_std::task::block_on](::async_std_crate::task::block_on()). This is not available on Wasm
34	/// as Wasm does not have threads and you're not allowed to block the only thread you have.
35	//
36	#[cfg(not(target_os = "unknown"))]
37	#[ cfg_attr( nightly, doc(cfg(not( target_os = "unknown" ))) ) ]
38	//
39	pub fn block_on<F: std::future::Future>(future: F) -> F::Output
40	{
41		async_std::task::block_on( future )
42	}
43}
44
45
46
47#[ cfg( target_arch = "wasm32" ) ]
48//
49impl Spawn for AsyncStd
50{
51	fn spawn_obj( &self, future: FutureObj<'static, ()> ) -> Result<(), SpawnError>
52	{
53		async_std::task::spawn_local( future );
54
55		Ok(())
56	}
57}
58
59
60
61#[ cfg(not( target_arch = "wasm32" )) ]
62//
63impl Spawn for AsyncStd
64{
65	fn spawn_obj( &self, future: FutureObj<'static, ()> ) -> Result<(), SpawnError>
66	{
67		async_std::task::spawn( future );
68
69		Ok(())
70	}
71}
72
73
74
75#[ cfg( not(target_arch = "wasm32") ) ]
76//
77impl<Out: 'static + Send> SpawnHandle<Out> for AsyncStd
78{
79	fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
80	{
81		let (fut, a_handle) = abortable( future );
82		let handle          = async_std::task::spawn( fut );
83
84		Ok( JoinHandle::async_std(handle, a_handle) )
85	}
86}
87
88
89
90// async-std only exposes local_spawn on wasm.
91//
92#[ cfg( target_arch = "wasm32" ) ]
93//
94impl<Out: 'static + Send> SpawnHandle<Out> for AsyncStd
95{
96	fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
97	{
98		let (fut, a_handle) = abortable( future );
99		let handle          = async_std::task::spawn_local( fut );
100
101		Ok( JoinHandle::async_std(handle, a_handle) )
102
103	}
104}
105
106
107
108impl<Out: 'static> LocalSpawnHandle<Out> for AsyncStd
109{
110	fn spawn_handle_local_obj( &self, future: LocalFutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
111	{
112		let (fut, a_handle) = abortable( future );
113		let handle = async_std::task::spawn_local( fut );
114
115		Ok( JoinHandle::async_std(handle, a_handle))
116	}
117}
118
119
120
121impl LocalSpawn for AsyncStd
122{
123	fn spawn_local_obj( &self, future: LocalFutureObj<'static, ()> ) -> Result<(), SpawnError>
124	{
125		// We drop the JoinHandle, so the task becomes detached.
126		//
127		drop( async_std::task::spawn_local(future) );
128
129		Ok(())
130	}
131}
132
133
134
135impl crate::YieldNow for AsyncStd {}
136
137
138
139#[ cfg( not(target_arch = "wasm32") ) ]
140//
141impl<R: Send + 'static> crate::SpawnBlocking<R> for AsyncStd
142{
143	fn spawn_blocking<F>( &self, f: F ) -> crate::BlockingHandle<R>
144
145		where F: FnOnce() -> R + Send + 'static ,
146	{
147		let handle = async_std::task::spawn_blocking( f );
148
149		crate::BlockingHandle::async_std( handle )
150	}
151
152
153	fn spawn_blocking_dyn( &self, f: Box< dyn FnOnce()->R + Send > ) -> crate::BlockingHandle<R>
154	{
155		self.spawn_blocking( f )
156	}
157}
158
159
160
161impl std::fmt::Debug for AsyncStd
162{
163	fn fmt( &self, f: &mut std::fmt::Formatter<'_> ) -> std::fmt::Result
164	{
165		write!( f, "AsyncStd executor" )
166	}
167}
168
169
170
171/// Signal io can be used on this executor.
172//
173#[ cfg(all( not(target_arch = "wasm32"), feature="async_std_tokio" )) ]
174//
175#[ cfg_attr( nightly, doc(cfg(all( not(target_arch = "wasm32"), feature="async_std_tokio" ))) ) ]
176//
177impl crate::TokioIo for AsyncStd {}
178
179
180
181
182
183
184#[ cfg(not( target_arch = "wasm32" )) ]
185//
186impl crate::Timer for AsyncStd
187{
188	fn sleep( &self, dur: std::time::Duration ) -> futures_core::future::BoxFuture<'static, ()>
189	{
190		Box::pin( async_std::task::sleep(dur) )
191	}
192}
193
194
195
196
197
198// On wasm async_std future is not Send, so use futures-timer.
199//
200#[ cfg(all( target_arch = "wasm32", feature = "timer" )) ]
201//
202impl crate::Timer for AsyncStd
203{
204	fn sleep( &self, dur: std::time::Duration ) -> futures_core::future::BoxFuture<'static, ()>
205	{
206		Box::pin( futures_timer::Delay::new(dur) )
207	}
208}
209
210