1
+ //! An unbounded set of futures.
2
+
1
3
use std:: cell:: UnsafeCell ;
2
4
use std:: fmt:: { self , Debug } ;
3
5
use std:: iter:: FromIterator ;
@@ -9,7 +11,7 @@ use std::sync::atomic::{AtomicPtr, AtomicBool};
9
11
use std:: sync:: { Arc , Weak } ;
10
12
use std:: usize;
11
13
12
- use { task, Stream , Future , Poll , Async , IntoFuture } ;
14
+ use { task, Stream , Future , Poll , Async } ;
13
15
use executor:: { Notify , UnsafeNotify , NotifyHandle } ;
14
16
use task_impl:: { self , AtomicTask } ;
15
17
@@ -51,29 +53,6 @@ pub struct FuturesUnordered<F> {
51
53
unsafe impl < T : Send > Send for FuturesUnordered < T > { }
52
54
unsafe impl < T : Sync > Sync for FuturesUnordered < T > { }
53
55
54
- /// Converts a list of futures into a `Stream` of results from the futures.
55
- ///
56
- /// This function will take an list of futures (e.g. a vector, an iterator,
57
- /// etc), and return a stream. The stream will yield items as they become
58
- /// available on the futures internally, in the order that they become
59
- /// available. This function is similar to `buffer_unordered` in that it may
60
- /// return items in a different order than in the list specified.
61
- ///
62
- /// Note that the returned set can also be used to dynamically push more
63
- /// futures into the set as they become available.
64
- pub fn futures_unordered < I > ( futures : I ) -> FuturesUnordered < <I :: Item as IntoFuture >:: Future >
65
- where I : IntoIterator ,
66
- I :: Item : IntoFuture
67
- {
68
- let mut set = FuturesUnordered :: new ( ) ;
69
-
70
- for future in futures {
71
- set. push ( future. into_future ( ) ) ;
72
- }
73
-
74
- return set
75
- }
76
-
77
56
// FuturesUnordered is implemented using two linked lists. One which links all
78
57
// futures managed by a `FuturesUnordered` and one that tracks futures that have
79
58
// been scheduled for polling. The first linked list is not thread safe and is
@@ -207,6 +186,15 @@ impl<T> FuturesUnordered<T> {
207
186
self . inner . enqueue ( ptr) ;
208
187
}
209
188
189
+ /// Returns an iterator that allows modifying each future in the set.
190
+ pub fn iter_mut ( & mut self ) -> IterMut < T > {
191
+ IterMut {
192
+ node : self . head_all ,
193
+ len : self . len ,
194
+ _marker : PhantomData
195
+ }
196
+ }
197
+
210
198
fn release_node ( & mut self , node : Arc < Node < T > > ) {
211
199
// The future is done, try to reset the queued flag. This will prevent
212
200
// `notify` from doing any work in the future
@@ -440,6 +428,37 @@ impl<F: Future> FromIterator<F> for FuturesUnordered<F> {
440
428
}
441
429
}
442
430
431
+ #[ derive( Debug ) ]
432
+ /// Mutable iterator over all futures in the unordered set.
433
+ pub struct IterMut < ' a , F : ' a > {
434
+ node : * const Node < F > ,
435
+ len : usize ,
436
+ _marker : PhantomData < & ' a mut FuturesUnordered < F > >
437
+ }
438
+
439
+ impl < ' a , F > Iterator for IterMut < ' a , F > {
440
+ type Item = & ' a mut F ;
441
+
442
+ fn next ( & mut self ) -> Option < & ' a mut F > {
443
+ if self . node . is_null ( ) {
444
+ return None ;
445
+ }
446
+ unsafe {
447
+ let future = ( * ( * self . node ) . future . get ( ) ) . as_mut ( ) . unwrap ( ) ;
448
+ let next = * ( * self . node ) . next_all . get ( ) ;
449
+ self . node = next;
450
+ self . len -= 1 ;
451
+ return Some ( future) ;
452
+ }
453
+ }
454
+
455
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
456
+ ( self . len , Some ( self . len ) )
457
+ }
458
+ }
459
+
460
+ impl < ' a , F > ExactSizeIterator for IterMut < ' a , F > { }
461
+
443
462
impl < T > Inner < T > {
444
463
/// The enqueue function from the 1024cores intrusive MPSC queue algorithm.
445
464
fn enqueue ( & self , node : * const Node < T > ) {
0 commit comments