@@ -199,21 +199,27 @@ impl<'a> Executor<'a> {
199
199
futures : impl IntoIterator < Item = F > ,
200
200
handles : & mut impl Extend < Task < F :: Output > > ,
201
201
) {
202
- let mut active = self . state ( ) . active . lock ( ) . unwrap ( ) ;
202
+ let mut active = Some ( self . state ( ) . active . lock ( ) . unwrap ( ) ) ;
203
203
204
- for ( i, future) in futures. into_iter ( ) . enumerate ( ) {
204
+ // Convert the futures into tasks.
205
+ let tasks = futures. into_iter ( ) . enumerate ( ) . map ( move |( i, future) | {
205
206
// SAFETY: `T` and the future are `Send`.
206
- handles . extend ( Some ( unsafe { self . spawn_inner ( future, & mut active) } ) ) ;
207
+ let task = unsafe { self . spawn_inner ( future, active. as_mut ( ) . unwrap ( ) ) } ;
207
208
208
209
// Yield the lock every once in a while to ease contention.
209
210
if i. wrapping_sub ( 1 ) % 500 == 0 {
210
- drop ( active) ;
211
- active = self . state ( ) . active . lock ( ) . unwrap ( ) ;
211
+ drop ( active. take ( ) ) ;
212
+ active = Some ( self . state ( ) . active . lock ( ) . unwrap ( ) ) ;
212
213
}
213
- }
214
+
215
+ task
216
+ } ) ;
217
+
218
+ // Push the tasks to the user's collection.
219
+ handles. extend ( tasks) ;
214
220
}
215
221
216
- /// Spawn a future using the inner lock.
222
+ /// Spawn a future while holding the inner lock.
217
223
///
218
224
/// # Safety
219
225
///
@@ -527,16 +533,14 @@ impl<'a> LocalExecutor<'a> {
527
533
let tasks = futures. into_iter ( ) . map ( |future| {
528
534
// SAFETY: This executor is not thread safe, so the future and its result
529
535
// cannot be sent to another thread.
530
- unsafe {
531
- self . inner ( ) . spawn_inner ( future, & mut active)
532
- }
536
+ unsafe { self . inner ( ) . spawn_inner ( future, & mut active) }
533
537
534
538
// As only one thread can spawn or poll tasks at a time, there is no need
535
539
// to release lock contention here.
536
540
} ) ;
537
541
538
542
// Push them to the user's collection.
539
- handles. extend ( tasks) ;
543
+ handles. extend ( tasks) ;
540
544
}
541
545
542
546
/// Attempts to run a task if at least one is scheduled.
@@ -602,16 +606,6 @@ impl<'a> LocalExecutor<'a> {
602
606
self . inner ( ) . run ( future) . await
603
607
}
604
608
605
- /// Returns a function that schedules a runnable task when it gets woken up.
606
- fn schedule ( & self ) -> impl Fn ( Runnable ) + Send + Sync + ' static {
607
- let state = self . inner ( ) . state ( ) . clone ( ) ;
608
-
609
- move |runnable| {
610
- state. queue . push ( runnable) . unwrap ( ) ;
611
- state. notify ( ) ;
612
- }
613
- }
614
-
615
609
/// Returns a reference to the inner executor.
616
610
fn inner ( & self ) -> & Executor < ' a > {
617
611
& self . inner
@@ -1060,17 +1054,6 @@ fn debug_executor(executor: &Executor<'_>, name: &str, f: &mut fmt::Formatter<'_
1060
1054
. finish ( )
1061
1055
}
1062
1056
1063
- /// Container with one item.
1064
- ///
1065
- /// This implements `Extend` for one-off cases.
1066
- struct Container < T > ( Option < T > ) ;
1067
-
1068
- impl < T > Extend < T > for Container < T > {
1069
- fn extend < X : IntoIterator < Item = T > > ( & mut self , iter : X ) {
1070
- self . 0 = iter. into_iter ( ) . next ( ) ;
1071
- }
1072
- }
1073
-
1074
1057
/// Runs a closure when dropped.
1075
1058
struct CallOnDrop < F : FnMut ( ) > ( F ) ;
1076
1059
0 commit comments