@@ -58,7 +58,6 @@ use std::sync::Arc;
58
58
use std:: time:: Duration ;
59
59
60
60
use anyhow:: format_err;
61
- use crossbeam_channel:: { unbounded, Receiver , Sender } ;
62
61
use crossbeam_utils:: thread:: Scope ;
63
62
use jobserver:: { Acquired , Client , HelperThread } ;
64
63
use log:: { debug, info, trace} ;
@@ -73,6 +72,7 @@ use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
73
72
use crate :: core:: { PackageId , TargetKind } ;
74
73
use crate :: util;
75
74
use crate :: util:: diagnostic_server:: { self , DiagnosticPrinter } ;
75
+ use crate :: util:: Queue ;
76
76
use crate :: util:: { internal, profile, CargoResult , CargoResultExt , ProcessBuilder } ;
77
77
use crate :: util:: { Config , DependencyQueue } ;
78
78
use crate :: util:: { Progress , ProgressStyle } ;
@@ -98,8 +98,7 @@ struct DrainState<'a, 'cfg> {
98
98
total_units : usize ,
99
99
100
100
queue : DependencyQueue < Unit < ' a > , Artifact , Job > ,
101
- tx : Sender < Message > ,
102
- rx : Receiver < Message > ,
101
+ messages : Arc < Queue < Message > > ,
103
102
active : HashMap < JobId , Unit < ' a > > ,
104
103
compiled : HashSet < PackageId > ,
105
104
documented : HashSet < PackageId > ,
@@ -145,7 +144,7 @@ impl std::fmt::Display for JobId {
145
144
146
145
pub struct JobState < ' a > {
147
146
/// Channel back to the main thread to coordinate messages and such.
148
- tx : Sender < Message > ,
147
+ messages : Arc < Queue < Message > > ,
149
148
150
149
/// The job id that this state is associated with, used when sending
151
150
/// messages back to the main thread.
@@ -199,7 +198,7 @@ enum Message {
199
198
200
199
impl < ' a > JobState < ' a > {
201
200
pub fn running ( & self , cmd : & ProcessBuilder ) {
202
- let _ = self . tx . send ( Message :: Run ( self . id , cmd. to_string ( ) ) ) ;
201
+ self . messages . push ( Message :: Run ( self . id , cmd. to_string ( ) ) ) ;
203
202
}
204
203
205
204
pub fn build_plan (
@@ -208,17 +207,16 @@ impl<'a> JobState<'a> {
208
207
cmd : ProcessBuilder ,
209
208
filenames : Arc < Vec < OutputFile > > ,
210
209
) {
211
- let _ = self
212
- . tx
213
- . send ( Message :: BuildPlanMsg ( module_name, cmd, filenames) ) ;
210
+ self . messages
211
+ . push ( Message :: BuildPlanMsg ( module_name, cmd, filenames) ) ;
214
212
}
215
213
216
214
pub fn stdout ( & self , stdout : String ) {
217
- drop ( self . tx . send ( Message :: Stdout ( stdout) ) ) ;
215
+ self . messages . push ( Message :: Stdout ( stdout) ) ;
218
216
}
219
217
220
218
pub fn stderr ( & self , stderr : String ) {
221
- drop ( self . tx . send ( Message :: Stderr ( stderr) ) ) ;
219
+ self . messages . push ( Message :: Stderr ( stderr) ) ;
222
220
}
223
221
224
222
/// A method used to signal to the coordinator thread that the rmeta file
@@ -228,9 +226,8 @@ impl<'a> JobState<'a> {
228
226
/// produced once!
229
227
pub fn rmeta_produced ( & self ) {
230
228
self . rmeta_required . set ( false ) ;
231
- let _ = self
232
- . tx
233
- . send ( Message :: Finish ( self . id , Artifact :: Metadata , Ok ( ( ) ) ) ) ;
229
+ self . messages
230
+ . push ( Message :: Finish ( self . id , Artifact :: Metadata , Ok ( ( ) ) ) ) ;
234
231
}
235
232
236
233
/// The rustc underlying this Job is about to acquire a jobserver token (i.e., block)
@@ -239,14 +236,14 @@ impl<'a> JobState<'a> {
239
236
/// This should arrange for the associated client to eventually get a token via
240
237
/// `client.release_raw()`.
241
238
pub fn will_acquire ( & self ) {
242
- let _ = self . tx . send ( Message :: NeedsToken ( self . id ) ) ;
239
+ self . messages . push ( Message :: NeedsToken ( self . id ) ) ;
243
240
}
244
241
245
242
/// The rustc underlying this Job is informing us that it is done with a jobserver token.
246
243
///
247
244
/// Note that it does *not* write that token back anywhere.
248
245
pub fn release_token ( & self ) {
249
- let _ = self . tx . send ( Message :: ReleaseToken ( self . id ) ) ;
246
+ self . messages . push ( Message :: ReleaseToken ( self . id ) ) ;
250
247
}
251
248
}
252
249
@@ -340,21 +337,18 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
340
337
let _p = profile:: start ( "executing the job graph" ) ;
341
338
self . queue . queue_finished ( ) ;
342
339
343
- let ( tx, rx) = unbounded ( ) ;
344
340
let progress = Progress :: with_style ( "Building" , ProgressStyle :: Ratio , cx. bcx . config ) ;
345
341
let state = DrainState {
346
342
total_units : self . queue . len ( ) ,
347
343
queue : self . queue ,
348
- tx,
349
- rx,
344
+ messages : Arc :: new ( Queue :: new ( ) ) ,
350
345
active : HashMap :: new ( ) ,
351
346
compiled : HashSet :: new ( ) ,
352
347
documented : HashSet :: new ( ) ,
353
348
counts : self . counts ,
354
349
progress,
355
350
next_id : 0 ,
356
351
timings : self . timings ,
357
-
358
352
tokens : Vec :: new ( ) ,
359
353
rustc_tokens : HashMap :: new ( ) ,
360
354
to_send_clients : BTreeMap :: new ( ) ,
@@ -364,25 +358,25 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
364
358
} ;
365
359
366
360
// Create a helper thread for acquiring jobserver tokens
367
- let tx = state. tx . clone ( ) ;
361
+ let messages = state. messages . clone ( ) ;
368
362
let helper = cx
369
363
. jobserver
370
364
. clone ( )
371
365
. into_helper_thread ( move |token| {
372
- drop ( tx . send ( Message :: Token ( token) ) ) ;
366
+ drop ( messages . push ( Message :: Token ( token) ) ) ;
373
367
} )
374
368
. chain_err ( || "failed to create helper thread for jobserver management" ) ?;
375
369
376
370
// Create a helper thread to manage the diagnostics for rustfix if
377
371
// necessary.
378
- let tx = state. tx . clone ( ) ;
372
+ let messages = state. messages . clone ( ) ;
379
373
let _diagnostic_server = cx
380
374
. bcx
381
375
. build_config
382
376
. rustfix_diagnostic_server
383
377
. borrow_mut ( )
384
378
. take ( )
385
- . map ( move |srv| srv. start ( move |msg| drop ( tx . send ( Message :: FixDiagnostic ( msg) ) ) ) ) ;
379
+ . map ( move |srv| srv. start ( move |msg| drop ( messages . push ( Message :: FixDiagnostic ( msg) ) ) ) ) ;
386
380
387
381
crossbeam_utils:: thread:: scope ( move |scope| state. drain_the_queue ( cx, plan, scope, & helper) )
388
382
. expect ( "child threads shouldn't panic" )
@@ -584,7 +578,10 @@ impl<'a, 'cfg> DrainState<'a, 'cfg> {
584
578
// to run above to calculate CPU usage over time. To do this we
585
579
// listen for a message with a timeout, and on timeout we run the
586
580
// previous parts of the loop again.
587
- let events: Vec < _ > = self . rx . try_iter ( ) . collect ( ) ;
581
+ let mut events = Vec :: new ( ) ;
582
+ while let Some ( event) = self . messages . try_pop ( ) {
583
+ events. push ( event) ;
584
+ }
588
585
info ! (
589
586
"tokens in use: {}, rustc_tokens: {:?}, waiting_rustcs: {:?} (events this tick: {})" ,
590
587
self . tokens. len( ) ,
@@ -602,14 +599,16 @@ impl<'a, 'cfg> DrainState<'a, 'cfg> {
602
599
loop {
603
600
self . tick_progress ( ) ;
604
601
self . tokens . truncate ( self . active . len ( ) - 1 ) ;
605
- match self . rx . recv_timeout ( Duration :: from_millis ( 500 ) ) {
606
- Ok ( message) => break vec ! [ message] ,
607
- Err ( _) => continue ,
602
+ match self . messages . pop ( Duration :: from_millis ( 500 ) ) {
603
+ Some ( message) => {
604
+ events. push ( message) ;
605
+ break ;
606
+ }
607
+ None => continue ,
608
608
}
609
609
}
610
- } else {
611
- events
612
610
}
611
+ return events;
613
612
}
614
613
615
614
fn drain_the_queue (
@@ -756,7 +755,7 @@ impl<'a, 'cfg> DrainState<'a, 'cfg> {
756
755
assert ! ( self . active. insert( id, * unit) . is_none( ) ) ;
757
756
* self . counts . get_mut ( & unit. pkg . package_id ( ) ) . unwrap ( ) -= 1 ;
758
757
759
- let my_tx = self . tx . clone ( ) ;
758
+ let messages = self . messages . clone ( ) ;
760
759
let fresh = job. freshness ( ) ;
761
760
let rmeta_required = cx. rmeta_required ( unit) ;
762
761
@@ -768,13 +767,13 @@ impl<'a, 'cfg> DrainState<'a, 'cfg> {
768
767
let doit = move || {
769
768
let state = JobState {
770
769
id,
771
- tx : my_tx . clone ( ) ,
770
+ messages : messages . clone ( ) ,
772
771
rmeta_required : Cell :: new ( rmeta_required) ,
773
772
_marker : marker:: PhantomData ,
774
773
} ;
775
774
776
775
let mut sender = FinishOnDrop {
777
- tx : & my_tx ,
776
+ messages : & messages ,
778
777
id,
779
778
result : Err ( format_err ! ( "worker panicked" ) ) ,
780
779
} ;
@@ -793,25 +792,24 @@ impl<'a, 'cfg> DrainState<'a, 'cfg> {
793
792
// we need to make sure that the metadata is flagged as produced so
794
793
// send a synthetic message here.
795
794
if state. rmeta_required . get ( ) && sender. result . is_ok ( ) {
796
- my_tx
797
- . send ( Message :: Finish ( id, Artifact :: Metadata , Ok ( ( ) ) ) )
798
- . unwrap ( ) ;
795
+ messages. push ( Message :: Finish ( id, Artifact :: Metadata , Ok ( ( ) ) ) ) ;
799
796
}
800
797
801
798
// Use a helper struct with a `Drop` implementation to guarantee
802
799
// that a `Finish` message is sent even if our job panics. We
803
800
// shouldn't panic unless there's a bug in Cargo, so we just need
804
801
// to make sure nothing hangs by accident.
805
802
struct FinishOnDrop < ' a > {
806
- tx : & ' a Sender < Message > ,
803
+ messages : & ' a Queue < Message > ,
807
804
id : JobId ,
808
805
result : CargoResult < ( ) > ,
809
806
}
810
807
811
808
impl Drop for FinishOnDrop < ' _ > {
812
809
fn drop ( & mut self ) {
813
810
let msg = mem:: replace ( & mut self . result , Ok ( ( ) ) ) ;
814
- drop ( self . tx . send ( Message :: Finish ( self . id , Artifact :: All , msg) ) ) ;
811
+ self . messages
812
+ . push ( Message :: Finish ( self . id , Artifact :: All , msg) ) ;
815
813
}
816
814
}
817
815
} ;
0 commit comments