@@ -14,6 +14,7 @@ use core::{PackageId, Target};
1414use handle_error;
1515use util:: { internal, profile, CargoResult , CargoResultExt , ProcessBuilder } ;
1616use util:: { Config , DependencyQueue , Dirty , Fresh , Freshness } ;
17+ use util:: Progress ;
1718
1819use super :: job:: Job ;
1920use super :: { BuildContext , BuildPlan , CompileMode , Context , Kind , Unit } ;
@@ -28,7 +29,7 @@ pub struct JobQueue<'a> {
2829 queue : DependencyQueue < Key < ' a > , Vec < ( Job , Freshness ) > > ,
2930 tx : Sender < Message < ' a > > ,
3031 rx : Receiver < Message < ' a > > ,
31- active : usize ,
32+ active : HashSet < Key < ' a > > ,
3233 pending : HashMap < Key < ' a > , PendingBuild > ,
3334 compiled : HashSet < & ' a PackageId > ,
3435 documented : HashSet < & ' a PackageId > ,
@@ -98,7 +99,7 @@ impl<'a> JobQueue<'a> {
9899 queue : DependencyQueue :: new ( ) ,
99100 tx,
100101 rx,
101- active : 0 ,
102+ active : HashSet :: new ( ) ,
102103 pending : HashMap :: new ( ) ,
103104 compiled : HashSet :: new ( ) ,
104105 documented : HashSet :: new ( ) ,
@@ -180,6 +181,8 @@ impl<'a> JobQueue<'a> {
180181 // successful and otherwise wait for pending work to finish if it failed
181182 // and then immediately return.
182183 let mut error = None ;
184+ let mut progress = Progress :: new ( "Building" , cx. bcx . config ) ;
185+ let queue_len = self . queue . len ( ) ;
183186 loop {
184187 // Dequeue as much work as we can, learning about everything
185188 // possible that can run. Note that this is also the point where we
@@ -196,7 +199,7 @@ impl<'a> JobQueue<'a> {
196199 ) ;
197200 for ( job, f) in jobs {
198201 queue. push ( ( key, job, f. combine ( fresh) ) ) ;
199- if self . active + queue. len ( ) > 0 {
202+ if ! self . active . is_empty ( ) || ! queue. is_empty ( ) {
200203 jobserver_helper. request_token ( ) ;
201204 }
202205 }
@@ -205,14 +208,14 @@ impl<'a> JobQueue<'a> {
205208 // Now that we've learned of all possible work that we can execute
206209 // try to spawn it so long as we've got a jobserver token which says
207210 // we're able to perform some parallel work.
208- while error. is_none ( ) && self . active < tokens. len ( ) + 1 && !queue. is_empty ( ) {
211+ while error. is_none ( ) && self . active . len ( ) < tokens. len ( ) + 1 && !queue. is_empty ( ) {
209212 let ( key, job, fresh) = queue. remove ( 0 ) ;
210213 self . run ( key, fresh, job, cx. bcx . config , scope, build_plan) ?;
211214 }
212215
213216 // If after all that we're not actually running anything then we're
214217 // done!
215- if self . active == 0 {
218+ if self . active . is_empty ( ) {
216219 break ;
217220 }
218221
@@ -221,9 +224,19 @@ impl<'a> JobQueue<'a> {
221224 // jobserver interface is architected we may acquire a token that we
222225 // don't actually use, and if this happens just relinquish it back
223226 // to the jobserver itself.
224- tokens. truncate ( self . active - 1 ) ;
225-
226- match self . rx . recv ( ) . unwrap ( ) {
227+ tokens. truncate ( self . active . len ( ) - 1 ) ;
228+
229+ let count = queue_len - self . queue . len ( ) ;
230+ let mut active_names = self . active . iter ( ) . map ( |key| match key. mode {
231+ CompileMode :: Doc { .. } => format ! ( "{}(doc)" , key. pkg. name( ) ) ,
232+ _ => key. pkg . name ( ) . to_string ( ) ,
233+ } ) . collect :: < Vec < _ > > ( ) ;
234+ active_names. sort_unstable ( ) ;
235+ drop ( progress. tick_now ( count, queue_len, format ! ( ": {}" , active_names. join( ", " ) ) ) ) ;
236+ let event = self . rx . recv ( ) . unwrap ( ) ;
237+ progress. clear ( ) ;
238+
239+ match event {
227240 Message :: Run ( cmd) => {
228241 cx. bcx
229242 . config
@@ -245,8 +258,9 @@ impl<'a> JobQueue<'a> {
245258 }
246259 Message :: Finish ( key, result) => {
247260 info ! ( "end: {:?}" , key) ;
248- self . active -= 1 ;
249- if self . active > 0 {
261+
262+ self . active . remove ( & key) ;
263+ if !self . active . is_empty ( ) {
250264 assert ! ( !tokens. is_empty( ) ) ;
251265 drop ( tokens. pop ( ) ) ;
252266 }
@@ -256,7 +270,7 @@ impl<'a> JobQueue<'a> {
256270 let msg = "The following warnings were emitted during compilation:" ;
257271 self . emit_warnings ( Some ( msg) , & key, cx) ?;
258272
259- if self . active > 0 {
273+ if ! self . active . is_empty ( ) {
260274 error = Some ( format_err ! ( "build failed" ) ) ;
261275 handle_error ( e, & mut * cx. bcx . config . shell ( ) ) ;
262276 cx. bcx . config . shell ( ) . warn (
@@ -274,6 +288,7 @@ impl<'a> JobQueue<'a> {
274288 }
275289 }
276290 }
291+ drop ( progress) ;
277292
278293 let build_type = if self . is_release { "release" } else { "dev" } ;
279294 // NOTE: This may be a bit inaccurate, since this may not display the
@@ -334,7 +349,7 @@ impl<'a> JobQueue<'a> {
334349 ) -> CargoResult < ( ) > {
335350 info ! ( "start: {:?}" , key) ;
336351
337- self . active += 1 ;
352+ self . active . insert ( key ) ;
338353 * self . counts . get_mut ( key. pkg ) . unwrap ( ) -= 1 ;
339354
340355 let my_tx = self . tx . clone ( ) ;
0 commit comments