@@ -14,6 +14,7 @@ use core::{PackageId, Target};
14
14
use handle_error;
15
15
use util:: { internal, profile, CargoResult , CargoResultExt , ProcessBuilder } ;
16
16
use util:: { Config , DependencyQueue , Dirty , Fresh , Freshness } ;
17
+ use util:: Progress ;
17
18
18
19
use super :: job:: Job ;
19
20
use super :: { BuildContext , BuildPlan , CompileMode , Context , Kind , Unit } ;
@@ -28,7 +29,7 @@ pub struct JobQueue<'a> {
28
29
queue : DependencyQueue < Key < ' a > , Vec < ( Job , Freshness ) > > ,
29
30
tx : Sender < Message < ' a > > ,
30
31
rx : Receiver < Message < ' a > > ,
31
- active : usize ,
32
+ active : HashSet < Key < ' a > > ,
32
33
pending : HashMap < Key < ' a > , PendingBuild > ,
33
34
compiled : HashSet < & ' a PackageId > ,
34
35
documented : HashSet < & ' a PackageId > ,
@@ -98,7 +99,7 @@ impl<'a> JobQueue<'a> {
98
99
queue : DependencyQueue :: new ( ) ,
99
100
tx,
100
101
rx,
101
- active : 0 ,
102
+ active : HashSet :: new ( ) ,
102
103
pending : HashMap :: new ( ) ,
103
104
compiled : HashSet :: new ( ) ,
104
105
documented : HashSet :: new ( ) ,
@@ -180,6 +181,8 @@ impl<'a> JobQueue<'a> {
180
181
// successful and otherwise wait for pending work to finish if it failed
181
182
// and then immediately return.
182
183
let mut error = None ;
184
+ let mut progress = Progress :: new ( "Building" , cx. bcx . config ) ;
185
+ let queue_len = self . queue . len ( ) ;
183
186
loop {
184
187
// Dequeue as much work as we can, learning about everything
185
188
// possible that can run. Note that this is also the point where we
@@ -196,7 +199,7 @@ impl<'a> JobQueue<'a> {
196
199
) ;
197
200
for ( job, f) in jobs {
198
201
queue. push ( ( key, job, f. combine ( fresh) ) ) ;
199
- if self . active + queue. len ( ) > 0 {
202
+ if ! self . active . is_empty ( ) || ! queue. is_empty ( ) {
200
203
jobserver_helper. request_token ( ) ;
201
204
}
202
205
}
@@ -205,14 +208,14 @@ impl<'a> JobQueue<'a> {
205
208
// Now that we've learned of all possible work that we can execute
206
209
// try to spawn it so long as we've got a jobserver token which says
207
210
// 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 ( ) {
209
212
let ( key, job, fresh) = queue. remove ( 0 ) ;
210
213
self . run ( key, fresh, job, cx. bcx . config , scope, build_plan) ?;
211
214
}
212
215
213
216
// If after all that we're not actually running anything then we're
214
217
// done!
215
- if self . active == 0 {
218
+ if self . active . is_empty ( ) {
216
219
break ;
217
220
}
218
221
@@ -221,9 +224,19 @@ impl<'a> JobQueue<'a> {
221
224
// jobserver interface is architected we may acquire a token that we
222
225
// don't actually use, and if this happens just relinquish it back
223
226
// 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 {
227
240
Message :: Run ( cmd) => {
228
241
cx. bcx
229
242
. config
@@ -245,8 +258,9 @@ impl<'a> JobQueue<'a> {
245
258
}
246
259
Message :: Finish ( key, result) => {
247
260
info ! ( "end: {:?}" , key) ;
248
- self . active -= 1 ;
249
- if self . active > 0 {
261
+
262
+ self . active . remove ( & key) ;
263
+ if !self . active . is_empty ( ) {
250
264
assert ! ( !tokens. is_empty( ) ) ;
251
265
drop ( tokens. pop ( ) ) ;
252
266
}
@@ -256,7 +270,7 @@ impl<'a> JobQueue<'a> {
256
270
let msg = "The following warnings were emitted during compilation:" ;
257
271
self . emit_warnings ( Some ( msg) , & key, cx) ?;
258
272
259
- if self . active > 0 {
273
+ if ! self . active . is_empty ( ) {
260
274
error = Some ( format_err ! ( "build failed" ) ) ;
261
275
handle_error ( e, & mut * cx. bcx . config . shell ( ) ) ;
262
276
cx. bcx . config . shell ( ) . warn (
@@ -274,6 +288,7 @@ impl<'a> JobQueue<'a> {
274
288
}
275
289
}
276
290
}
291
+ drop ( progress) ;
277
292
278
293
let build_type = if self . is_release { "release" } else { "dev" } ;
279
294
// NOTE: This may be a bit inaccurate, since this may not display the
@@ -334,7 +349,7 @@ impl<'a> JobQueue<'a> {
334
349
) -> CargoResult < ( ) > {
335
350
info ! ( "start: {:?}" , key) ;
336
351
337
- self . active += 1 ;
352
+ self . active . insert ( key ) ;
338
353
* self . counts . get_mut ( key. pkg ) . unwrap ( ) -= 1 ;
339
354
340
355
let my_tx = self . tx . clone ( ) ;
0 commit comments