@ -5,7 +5,7 @@ use std::thread;
use std ::time ::Duration ;
use crossbeam_channel ::{ bounded , Receiver , Sender } ;
use lazy_static::lazy_static ;
use once_cell::sync ::Lazy ;
use crate ::task ::task ::{ JoinHandle , Tag } ;
use crate ::utils ::abort_on_panic ;
@ -19,30 +19,30 @@ struct Pool {
receiver : Receiver < async_task ::Task < Tag > > ,
}
lazy_static ! {
static ref POOL : Pool = {
for _ in 0 .. 2 {
thread ::Builder ::new ( )
. name ( "async-blocking-driver" . to_string ( ) )
. spawn ( | | abort_on_panic ( | | {
static POOL : Lazy < Pool > = Lazy ::new ( | | {
for _ in 0 .. 2 {
thread ::Builder ::new ( )
. name ( "async-blocking-driver" . to_string ( ) )
. spawn ( | | {
abort_on_panic ( | | {
for task in & POOL . receiver {
task . run ( ) ;
}
} ) )
. expect ( "cannot start a thread driving blocking tasks" ) ;
}
// We want to use an unbuffered channel here to help
// us drive our dynamic control. In effect, the
// kernel's scheduler becomes the queue, reducing
// the number of buffers that work must flow through
// before being acted on by a core. This helps keep
// latency snappy in the overall async system by
// reducing bufferbloat.
let ( sender , receiver ) = bounded ( 0 ) ;
Pool { sender , receiver }
} ;
}
} )
} )
. expect ( "cannot start a thread driving blocking tasks" ) ;
}
// We want to use an unbuffered channel here to help
// us drive our dynamic control. In effect, the
// kernel's scheduler becomes the queue, reducing
// the number of buffers that work must flow through
// before being acted on by a core. This helps keep
// latency snappy in the overall async system by
// reducing bufferbloat.
let ( sender , receiver ) = bounded ( 0 ) ;
Pool { sender , receiver }
} ) ;
// Create up to MAX_THREADS dynamic blocking task worker threads.
// Dynamic threads will terminate themselves if they don't