@@ -26,6 +26,10 @@ pub enum JoinHandle<T> {
2626 #[ cfg( feature = "_rt-tokio" ) ]
2727 Tokio ( tokio:: task:: JoinHandle < T > ) ,
2828
29+ // WASI P3 runtime
30+ #[ cfg( target_arch = "wasm32" ) ]
31+ Wasip3 ( crate :: rt:: rt_wasip3:: JoinHandle < T > ) ,
32+
2933 // Implementation shared by `smol` and `async-global-executor`
3034 #[ cfg( feature = "_rt-async-task" ) ]
3135 AsyncTask ( Option < async_task:: Task < T > > ) ,
@@ -37,30 +41,20 @@ pub enum JoinHandle<T> {
3741pub async fn timeout < F : Future > ( duration : Duration , f : F ) -> Result < F :: Output , TimeoutError > {
3842 #[ cfg( target_arch = "wasm32" ) ]
3943 {
40- let timeout = crate :: rt :: rt_wasip3 :: spawn ( wasi :: clocks:: monotonic_clock:: wait_for (
44+ let timeout_future = wasip3 :: clocks:: monotonic_clock:: wait_for (
4145 duration. as_nanos ( ) . try_into ( ) . unwrap_or ( u64:: MAX ) ,
42- ) ) ;
43- let mut timeout = core:: pin:: pin!( timeout ) ;
46+ ) ;
47+ let mut timeout = core:: pin:: pin!( timeout_future ) ;
4448 let mut f = core:: pin:: pin!( f) ;
45- core:: future:: poll_fn ( |cx| {
46- match timeout. as_mut ( ) . poll ( cx) {
47- Poll :: Ready ( Some ( ( ) ) ) => {
48- Poll :: Ready ( Err ( TimeoutError ( ( ) ) ) )
49- }
50- Poll :: Ready ( None ) => {
51- Poll :: Ready ( Err ( TimeoutError ( ( ) ) ) )
52- }
53- Poll :: Pending => {
54- f. as_mut ( ) . poll ( cx) . map ( Ok )
55- }
56- }
49+
50+ return core:: future:: poll_fn ( |cx| match timeout. as_mut ( ) . poll ( cx) {
51+ Poll :: Ready ( _) => Poll :: Ready ( Err ( TimeoutError ) ) ,
52+ Poll :: Pending => f. as_mut ( ) . poll ( cx) . map ( Ok ) ,
5753 } )
58- . await
54+ . await ;
5955 }
6056
61- #[ cfg( all( feature = "_rt-tokio" , not( target_arch = "wasm32" ) ) ) ]
62- #[ cfg( debug_assertions) ]
63- let f = Box :: pin ( f) ;
57+ #[ cfg( feature = "_rt-tokio" ) ]
6458 if rt_tokio:: available ( ) {
6559 return tokio:: time:: timeout ( duration, f)
6660 . await
@@ -80,11 +74,11 @@ pub async fn timeout<F: Future>(duration: Duration, f: F) -> Result<F::Output, T
8074pub async fn sleep ( duration : Duration ) {
8175 #[ cfg( target_arch = "wasm32" ) ]
8276 {
83- return crate :: rt :: rt_wasip3 :: spawn ( wasi :: clocks:: monotonic_clock:: wait_for (
77+ wasip3 :: clocks:: monotonic_clock:: wait_for (
8478 duration. as_nanos ( ) . try_into ( ) . unwrap_or ( u64:: MAX ) ,
85- ) )
86- . await
87- . unwrap ( ) ;
79+ )
80+ . await ;
81+ return ;
8882 }
8983 #[ cfg( feature = "_rt-tokio" ) ]
9084 if rt_tokio:: available ( ) {
@@ -107,6 +101,11 @@ where
107101 F : Future + Send + ' static ,
108102 F :: Output : Send + ' static ,
109103{
104+ #[ cfg( target_arch = "wasm32" ) ]
105+ {
106+ return JoinHandle :: Wasip3 ( crate :: rt:: rt_wasip3:: spawn ( fut) ) ;
107+ }
108+
110109 #[ cfg( feature = "_rt-tokio" ) ]
111110 if let Ok ( handle) = tokio:: runtime:: Handle :: try_current ( ) {
112111 return JoinHandle :: Tokio ( handle. spawn ( fut) ) ;
@@ -124,15 +123,6 @@ where
124123 }
125124 }
126125}
127- #[ cfg( target_arch = "wasm32" ) ]
128- #[ track_caller]
129- pub fn spawn < F > ( fut : F ) -> JoinHandle < F :: Output >
130- where
131- F : Future + Send + ' static ,
132- F :: Output : Send + ' static ,
133- {
134- JoinHandle :: Tokio ( tokio:: task:: spawn ( fut) )
135- }
136126
137127#[ cfg( target_arch = "wasm32" ) ]
138128#[ track_caller]
@@ -141,8 +131,9 @@ where
141131 F : FnOnce ( ) -> R + Send + ' static ,
142132 R : Send + ' static ,
143133{
144- // In WASI P3, we use our async spawn_blocking implementation
145- JoinHandle :: Tokio ( tokio:: task:: spawn ( crate :: rt:: rt_wasip3:: spawn_blocking ( f) ) )
134+ JoinHandle :: Wasip3 ( crate :: rt:: rt_wasip3:: spawn (
135+ crate :: rt:: rt_wasip3:: spawn_blocking ( f) ,
136+ ) )
146137}
147138
148139#[ cfg( not( target_arch = "wasm32" ) ) ]
@@ -175,7 +166,7 @@ pub async fn yield_now() {
175166 {
176167 return crate :: rt:: rt_wasip3:: yield_now ( ) . await ;
177168 }
178-
169+
179170 #[ cfg( feature = "_rt-tokio" ) ]
180171 if rt_tokio:: available ( ) {
181172 return tokio:: task:: yield_now ( ) . await ;
@@ -204,14 +195,15 @@ pub async fn yield_now() {
204195 . await
205196}
206197
198+ #[ cfg( not( target_arch = "wasm32" ) ) ]
207199#[ track_caller]
208200pub fn test_block_on < F : Future > ( f : F ) -> F :: Output {
209201 #[ cfg( feature = "_rt-async-io" ) ]
210202 {
211203 return async_io:: block_on ( f) ;
212204 }
213205
214- #[ cfg( any ( feature = "_rt-tokio" , target_arch = "wasm32" ) ) ]
206+ #[ cfg( feature = "_rt-tokio" ) ]
215207 {
216208 return tokio:: runtime:: Builder :: new_current_thread ( )
217209 . enable_all ( )
@@ -223,7 +215,7 @@ pub fn test_block_on<F: Future>(f: F) -> F::Output {
223215 #[ cfg( all(
224216 feature = "_rt-async-std" ,
225217 not( feature = "_rt-async-io" ) ,
226- not( any ( feature = "_rt-tokio" , target_arch = "wasm32" ) )
218+ not( feature = "_rt-tokio" )
227219 ) ) ]
228220 {
229221 return async_std:: task:: block_on ( f) ;
@@ -232,14 +224,22 @@ pub fn test_block_on<F: Future>(f: F) -> F::Output {
232224 #[ cfg( not( any(
233225 feature = "_rt-async-io" ,
234226 feature = "_rt-async-std" ,
235- feature = "_rt-tokio" ,
236- target_arch = "wasm32"
227+ feature = "_rt-tokio"
237228 ) ) ) ]
238229 {
239230 missing_rt ( f)
240231 }
241232}
242233
234+ #[ cfg( target_arch = "wasm32" ) ]
235+ #[ track_caller]
236+ pub fn test_block_on < F : Future + ' static > ( f : F ) -> F :: Output
237+ where
238+ F :: Output : ' static ,
239+ {
240+ wasip3:: wit_bindgen:: rt:: async_support:: block_on ( f)
241+ }
242+
243243#[ track_caller]
244244pub const fn missing_rt < T > ( _unused : T ) -> ! {
245245 if cfg ! ( feature = "_rt-tokio" ) {
@@ -264,11 +264,14 @@ impl<T: Send + 'static> Future for JoinHandle<T> {
264264 . expect ( "BUG: task taken" )
265265 . poll ( cx) ,
266266
267- #[ cfg( any ( feature = "_rt-tokio" , target_arch = "wasm32" ) ) ]
267+ #[ cfg( feature = "_rt-tokio" ) ]
268268 Self :: Tokio ( handle) => Pin :: new ( handle)
269269 . poll ( cx)
270270 . map ( |res| res. expect ( "spawned task panicked" ) ) ,
271271
272+ #[ cfg( target_arch = "wasm32" ) ]
273+ Self :: Wasip3 ( handle) => Pin :: new ( handle) . poll ( cx) ,
274+
272275 Self :: _Phantom( _) => {
273276 let _ = cx;
274277 unreachable ! ( "runtime should have been checked on spawn" )
0 commit comments