Skip to content

Commit 440e2f0

Browse files
ibraheemdevtaiki-e
authored andcommitted
impl Send + Sync for FuturesUnordered iterators
1 parent 890d52c commit 440e2f0

File tree

2 files changed

+22
-17
lines changed

2 files changed

+22
-17
lines changed

futures-util/src/stream/futures_unordered/iter.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use super::FuturesUnordered;
21
use super::task::Task;
2+
use super::FuturesUnordered;
33
use core::marker::PhantomData;
44
use core::pin::Pin;
55
use core::sync::atomic::Ordering::Relaxed;
@@ -9,25 +9,25 @@ use core::sync::atomic::Ordering::Relaxed;
99
pub struct IterPinMut<'a, Fut> {
1010
pub(super) task: *const Task<Fut>,
1111
pub(super) len: usize,
12-
pub(super) _marker: PhantomData<&'a mut FuturesUnordered<Fut>>
12+
pub(super) _marker: PhantomData<&'a mut FuturesUnordered<Fut>>,
1313
}
1414

1515
#[derive(Debug)]
1616
/// Mutable iterator over all futures in the unordered set.
17-
pub struct IterMut<'a, Fut: Unpin> (pub(super) IterPinMut<'a, Fut>);
17+
pub struct IterMut<'a, Fut: Unpin>(pub(super) IterPinMut<'a, Fut>);
1818

1919
#[derive(Debug)]
2020
/// Immutable iterator over all futures in the unordered set.
2121
pub struct IterPinRef<'a, Fut> {
2222
pub(super) task: *const Task<Fut>,
2323
pub(super) len: usize,
2424
pub(super) pending_next_all: *mut Task<Fut>,
25-
pub(super) _marker: PhantomData<&'a FuturesUnordered<Fut>>
25+
pub(super) _marker: PhantomData<&'a FuturesUnordered<Fut>>,
2626
}
2727

2828
#[derive(Debug)]
2929
/// Immutable iterator over all the futures in the unordered set.
30-
pub struct Iter<'a, Fut: Unpin> (pub(super) IterPinRef<'a, Fut>);
30+
pub struct Iter<'a, Fut: Unpin>(pub(super) IterPinRef<'a, Fut>);
3131

3232
impl<'a, Fut> Iterator for IterPinMut<'a, Fut> {
3333
type Item = Pin<&'a mut Fut>;
@@ -85,10 +85,7 @@ impl<'a, Fut> Iterator for IterPinRef<'a, Fut> {
8585
// `head_all` was initially read for this iterator implies acquire
8686
// ordering for all previously inserted nodes (and we don't need to
8787
// read `len_all` again for any other nodes).
88-
let next = (*self.task).spin_next_all(
89-
self.pending_next_all,
90-
Relaxed,
91-
);
88+
let next = (*self.task).spin_next_all(self.pending_next_all, Relaxed);
9289
self.task = next;
9390
self.len -= 1;
9491
Some(Pin::new_unchecked(future))
@@ -115,3 +112,11 @@ impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
115112
}
116113

117114
impl<Fut: Unpin> ExactSizeIterator for Iter<'_, Fut> {}
115+
116+
// SAFETY: we do nothing thread-local and there is no interior mutability,
117+
// so the usual structural `Send`/`Sync` apply.
118+
unsafe impl<Fut: Send> Send for IterPinRef<'_, Fut> {}
119+
unsafe impl<Fut: Sync> Sync for IterPinRef<'_, Fut> {}
120+
121+
unsafe impl<Fut: Send> Send for IterPinMut<'_, Fut> {}
122+
unsafe impl<Fut: Sync> Sync for IterPinMut<'_, Fut> {}

futures/tests/auto_traits.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,24 +1780,24 @@ pub mod stream {
17801780
assert_not_impl!(Zip<UnpinStream, PinnedStream>: Unpin);
17811781
assert_not_impl!(Zip<PinnedStream, UnpinStream>: Unpin);
17821782

1783-
assert_not_impl!(futures_unordered::Iter<()>: Send);
1784-
assert_not_impl!(futures_unordered::Iter<()>: Sync);
1783+
assert_impl!(futures_unordered::Iter<()>: Send);
1784+
assert_impl!(futures_unordered::Iter<()>: Sync);
17851785
assert_impl!(futures_unordered::Iter<()>: Unpin);
17861786
// futures_unordered::Iter requires `Fut: Unpin`
17871787
// assert_not_impl!(futures_unordered::Iter<PhantomPinned>: Unpin);
17881788

1789-
assert_not_impl!(futures_unordered::IterMut<()>: Send);
1790-
assert_not_impl!(futures_unordered::IterMut<()>: Sync);
1789+
assert_impl!(futures_unordered::IterMut<()>: Send);
1790+
assert_impl!(futures_unordered::IterMut<()>: Sync);
17911791
assert_impl!(futures_unordered::IterMut<()>: Unpin);
17921792
// futures_unordered::IterMut requires `Fut: Unpin`
17931793
// assert_not_impl!(futures_unordered::IterMut<PhantomPinned>: Unpin);
17941794

1795-
assert_not_impl!(futures_unordered::IterPinMut<()>: Send);
1796-
assert_not_impl!(futures_unordered::IterPinMut<()>: Sync);
1795+
assert_impl!(futures_unordered::IterPinMut<()>: Send);
1796+
assert_impl!(futures_unordered::IterPinMut<()>: Sync);
17971797
assert_impl!(futures_unordered::IterPinMut<PhantomPinned>: Unpin);
17981798

1799-
assert_not_impl!(futures_unordered::IterPinRef<()>: Send);
1800-
assert_not_impl!(futures_unordered::IterPinRef<()>: Sync);
1799+
assert_impl!(futures_unordered::IterPinRef<()>: Send);
1800+
assert_impl!(futures_unordered::IterPinRef<()>: Sync);
18011801
assert_impl!(futures_unordered::IterPinRef<PhantomPinned>: Unpin);
18021802
}
18031803

0 commit comments

Comments
 (0)