@@ -272,14 +272,19 @@ pub(in crate::runtime) fn trace_current_thread(
272
272
injection : & Inject < Arc < current_thread:: Handle > > ,
273
273
) -> Vec < Trace > {
274
274
// clear the local and injection queues
275
- local. clear ( ) ;
275
+
276
+ let mut dequeued = Vec :: new ( ) ;
277
+
278
+ while let Some ( task) = local. pop_back ( ) {
279
+ dequeued. push ( task) ;
280
+ }
276
281
277
282
while let Some ( task) = injection. pop ( ) {
278
- drop ( task) ;
283
+ dequeued . push ( task) ;
279
284
}
280
285
281
286
// precondition: We have drained the tasks from the injection queue.
282
- trace_owned ( owned)
287
+ trace_owned ( owned, dequeued )
283
288
}
284
289
285
290
cfg_rt_multi_thread ! {
@@ -299,22 +304,24 @@ cfg_rt_multi_thread! {
299
304
synced: & Mutex <Synced >,
300
305
injection: & Shared <Arc <multi_thread:: Handle >>,
301
306
) -> Vec <Trace > {
307
+ let mut dequeued = Vec :: new( ) ;
308
+
302
309
// clear the local queue
303
310
while let Some ( notified) = local. pop( ) {
304
- drop ( notified) ;
311
+ dequeued . push ( notified) ;
305
312
}
306
313
307
314
// clear the injection queue
308
315
let mut synced = synced. lock( ) ;
309
316
while let Some ( notified) = injection. pop( & mut synced. inject) {
310
- drop ( notified) ;
317
+ dequeued . push ( notified) ;
311
318
}
312
319
313
320
drop( synced) ;
314
321
315
322
// precondition: we have drained the tasks from the local and injection
316
323
// queues.
317
- trace_owned( owned)
324
+ trace_owned( owned, dequeued )
318
325
}
319
326
}
320
327
@@ -324,12 +331,16 @@ cfg_rt_multi_thread! {
324
331
///
325
332
/// This helper presumes exclusive access to each task. The tasks must not exist
326
333
/// in any other queue.
327
- fn trace_owned < S : Schedule > ( owned : & OwnedTasks < S > ) -> Vec < Trace > {
334
+ fn trace_owned < S : Schedule > ( owned : & OwnedTasks < S > , dequeued : Vec < Notified < S > > ) -> Vec < Trace > {
328
335
// notify each task
329
- let mut tasks = vec ! [ ] ;
336
+ let mut tasks = dequeued ;
330
337
owned. for_each ( |task| {
331
- // notify the task (and thus make it poll-able) and stash it
332
- tasks. push ( task. notify_for_tracing ( ) ) ;
338
+ // Notify the task (and thus make it poll-able) and stash it. This fails
339
+ // if the task is already notified. In these cases, we skip tracing the
340
+ // task.
341
+ if let Some ( notified) = task. notify_for_tracing ( ) {
342
+ tasks. push ( notified) ;
343
+ }
333
344
// we do not poll it here since we hold a lock on `owned` and the task
334
345
// may complete and need to remove itself from `owned`.
335
346
} ) ;
0 commit comments