@@ -6,7 +6,7 @@ use crossbeam_channel::{unbounded, Receiver, Sender};
6
6
use once_cell:: sync:: Lazy ;
7
7
8
8
use crate :: task:: { JoinHandle , Task } ;
9
- use crate :: utils:: { abort_on_panic, random } ;
9
+ use crate :: utils:: abort_on_panic;
10
10
11
11
/// Spawns a blocking task.
12
12
///
@@ -68,16 +68,13 @@ static POOL: Lazy<Pool> = Lazy::new(|| {
68
68
69
69
fn start_thread ( ) {
70
70
SLEEPING . fetch_add ( 1 , Ordering :: SeqCst ) ;
71
-
72
- // Generate a random duration of time between 1 second and 10 seconds. If the thread doesn't
73
- // receive the next task in this duration of time, it will stop running.
74
- let timeout = Duration :: from_millis ( 1000 + u64:: from ( random ( 9_000 ) ) ) ;
71
+ let timeout = Duration :: from_secs ( 1 ) ;
75
72
76
73
thread:: Builder :: new ( )
77
74
. name ( "async-std/blocking" . to_string ( ) )
78
75
. spawn ( move || {
79
76
loop {
80
- let task = match POOL . receiver . recv_timeout ( timeout) {
77
+ let mut task = match POOL . receiver . recv_timeout ( timeout) {
81
78
Ok ( task) => task,
82
79
Err ( _) => {
83
80
// Check whether this is the last sleeping thread.
@@ -100,8 +97,22 @@ fn start_thread() {
100
97
start_thread ( ) ;
101
98
}
102
99
103
- // Run the task.
104
- abort_on_panic ( || task. run ( ) ) ;
100
+ loop {
101
+ // Run the task.
102
+ abort_on_panic ( || task. run ( ) ) ;
103
+
104
+ // Try taking another task if there are any available.
105
+ task = match POOL . receiver . try_recv ( ) {
106
+ Ok ( task) => task,
107
+ Err ( _) => break ,
108
+ } ;
109
+ }
110
+
111
+ // If there is at least one sleeping thread, stop this thread instead of putting it
112
+ // to sleep.
113
+ if SLEEPING . load ( Ordering :: SeqCst ) > 0 {
114
+ return ;
115
+ }
105
116
106
117
SLEEPING . fetch_add ( 1 , Ordering :: SeqCst ) ;
107
118
}
0 commit comments