@@ -12,6 +12,7 @@ use serde_json::from_value;
12
12
use std:: collections:: HashSet ;
13
13
use std:: str:: FromStr ;
14
14
use std:: sync:: { Arc , OnceLock } ;
15
+ use std:: time:: Duration ;
15
16
use thiserror:: Error ;
16
17
use tokio:: sync:: oneshot;
17
18
@@ -203,20 +204,32 @@ impl RuntimeSingleton {
203
204
let mut completers: Vec < Completer > = vec ! [ ] ;
204
205
205
206
loop {
206
- let mut completed = vec ! [ ] ;
207
- for ( index, completer) in completers. iter ( ) . enumerate ( ) {
208
- if completer. is_ready ( runtime) {
209
- completed. push ( index) ;
210
- }
211
- }
207
+ let completed = completers
208
+ . iter ( )
209
+ . enumerate ( )
210
+ . filter_map ( |( idx, completer) | {
211
+ if completer. is_ready ( runtime) {
212
+ Some ( idx)
213
+ } else {
214
+ None
215
+ }
216
+ } )
217
+ . collect :: < Vec < _ > > ( ) ;
212
218
213
- for index in completed. iter ( ) . rev ( ) {
214
- let completer = completers. swap_remove ( * index) ;
219
+ for index in completed. into_iter ( ) . rev ( ) {
220
+ let completer = completers. swap_remove ( index) ;
215
221
completer. resolve ( runtime) . await ;
216
222
}
223
+ let pending = !completers. is_empty ( ) ;
224
+
225
+ const DURATION : Option < Duration > = Some ( Duration :: from_millis ( 25 ) ) ;
226
+ const OPTS : PollEventLoopOptions = PollEventLoopOptions {
227
+ wait_for_inspector : false ,
228
+ pump_v8_message_loop : true ,
229
+ } ;
217
230
218
231
tokio:: select! {
219
- result = runtime. await_event_loop( PollEventLoopOptions :: default ( ) , Some ( std :: time :: Duration :: from_millis ( 25 ) ) ) , if !completers . is_empty ( ) => {
232
+ result = runtime. await_event_loop( OPTS , DURATION ) , if pending => {
220
233
if let Err ( err) = result{
221
234
log:: error!( "JS event loop: {err}" ) ;
222
235
}
@@ -272,48 +285,52 @@ impl RuntimeSingleton {
272
285
} )
273
286
. unzip ( ) ;
274
287
275
- let root_thread = std:: thread:: spawn ( move || {
276
- init_platform ( n_threads as u32 , true ) ;
277
-
278
- let threads: Vec < _ > = receivers
279
- . into_iter ( )
280
- . enumerate ( )
281
- . map ( |( index, receiver) | {
282
- let shared_receiver = shared_receiver. clone ( ) ;
283
-
284
- return std:: thread:: spawn ( move || {
285
- let tokio_runtime = std:: rc:: Rc :: new (
286
- tokio:: runtime:: Builder :: new_current_thread ( )
287
- . enable_time ( )
288
- . enable_io ( )
289
- . thread_name ( "v8-runtime" )
290
- . build ( )
291
- . unwrap ( ) ,
292
- ) ;
293
-
294
- let mut js_runtime = match Self :: init_runtime ( index, tokio_runtime. clone ( ) ) {
295
- Ok ( js_runtime) => js_runtime,
296
- Err ( err) => {
297
- panic ! ( "Failed to init v8 runtime on thread {index}: {err}" ) ;
298
- }
299
- } ;
300
-
301
- Self :: event_loop ( & mut js_runtime, receiver, shared_receiver) ;
302
- } ) ;
303
- } )
304
- . collect ( ) ;
305
-
306
- for ( idx, thread) in threads. into_iter ( ) . enumerate ( ) {
307
- if let Err ( err) = thread. join ( ) {
308
- log:: error!( "Failed to join worker: {idx}: {err:?}" ) ;
288
+ let handle = if n_threads > 0 {
289
+ Some ( std:: thread:: spawn ( move || {
290
+ init_platform ( n_threads as u32 , true ) ;
291
+
292
+ let threads: Vec < _ > = receivers
293
+ . into_iter ( )
294
+ . enumerate ( )
295
+ . map ( |( index, receiver) | {
296
+ let shared_receiver = shared_receiver. clone ( ) ;
297
+
298
+ return std:: thread:: spawn ( move || {
299
+ let tokio_runtime = std:: rc:: Rc :: new (
300
+ tokio:: runtime:: Builder :: new_current_thread ( )
301
+ . enable_time ( )
302
+ . enable_io ( )
303
+ . thread_name ( "v8-runtime" )
304
+ . build ( )
305
+ . unwrap ( ) ,
306
+ ) ;
307
+
308
+ let mut js_runtime = match Self :: init_runtime ( index, tokio_runtime. clone ( ) ) {
309
+ Ok ( js_runtime) => js_runtime,
310
+ Err ( err) => {
311
+ panic ! ( "Failed to init v8 runtime on thread {index}: {err}" ) ;
312
+ }
313
+ } ;
314
+
315
+ Self :: event_loop ( & mut js_runtime, receiver, shared_receiver) ;
316
+ } ) ;
317
+ } )
318
+ . collect ( ) ;
319
+
320
+ for ( idx, thread) in threads. into_iter ( ) . enumerate ( ) {
321
+ if let Err ( err) = thread. join ( ) {
322
+ log:: error!( "Failed to join worker: {idx}: {err:?}" ) ;
323
+ }
309
324
}
310
- }
311
- } ) ;
325
+ } ) )
326
+ } else {
327
+ None
328
+ } ;
312
329
313
330
return RuntimeSingleton {
314
331
n_threads,
315
332
sender : shared_sender,
316
- handle : Some ( root_thread ) ,
333
+ handle,
317
334
state,
318
335
} ;
319
336
}
0 commit comments