Skip to content

Commit 17d7ed0

Browse files
committed
fix potential race condition
1 parent 5f192fa commit 17d7ed0

File tree

2 files changed

+20
-25
lines changed

2 files changed

+20
-25
lines changed

src/arc_slice.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub(crate) struct ArcSliceInnerMeta {
6363
pub(crate) struct ArcSlotInner {
6464
index: usize,
6565
wake_lock: AtomicBool,
66-
woken: AtomicBool,
66+
// woken: AtomicBool,
6767
next: AtomicUsize,
6868
}
6969

@@ -135,24 +135,14 @@ impl ArcSliceInner {
135135
/// https://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
136136
///
137137
/// Safety: index must be within capacity
138-
pub(crate) unsafe fn push(&self, index: usize) -> bool {
138+
pub(crate) unsafe fn push(&self, index: usize) {
139139
let node = self.slice.get_unchecked(index);
140-
141-
node.woken.store(true, Ordering::Relaxed);
142-
// if node.wake_lock.swap(true, Ordering::SeqCst) {
143-
// // already woken
144-
// return false;
145-
// }
146-
147140
node.next.store(usize::MAX, Ordering::Relaxed);
148141

149142
let prev = self.meta.list_head.swap(index, Ordering::AcqRel);
150-
self.slice
151-
.get_unchecked(prev)
152-
.next
153-
.store(index, Ordering::Release);
154143

155-
true
144+
let prev_node = self.slice.get_unchecked(prev);
145+
prev_node.next.store(index, Ordering::Release);
156146
}
157147

158148
/// The pop function from the 1024cores intrusive MPSC queue algorithm
@@ -174,11 +164,11 @@ impl ArcSliceInner {
174164
next = self.slice.get_unchecked(next).next.load(Ordering::Acquire);
175165
}
176166

177-
if next <= self.meta.len {
167+
if next != usize::MAX {
178168
*self.meta.list_tail.get() = next;
179169
debug_assert!(tail != self.meta.len);
180170

181-
// self.slice[tail].wake_lock.store(false, Ordering::SeqCst);
171+
self.slice[tail].wake_lock.store(false, Ordering::SeqCst);
182172
return ReadySlot::Ready(tail);
183173
}
184174

@@ -190,10 +180,10 @@ impl ArcSliceInner {
190180

191181
next = self.slice.get_unchecked(tail).next.load(Ordering::Acquire);
192182

193-
if next <= self.meta.len {
183+
if next != usize::MAX {
194184
*self.meta.list_tail.get() = next;
195185

196-
// self.slice[tail].wake_lock.store(false, Ordering::SeqCst);
186+
self.slice[tail].wake_lock.store(false, Ordering::SeqCst);
197187
return ReadySlot::Ready(tail);
198188
}
199189

@@ -212,6 +202,7 @@ mod slot {
212202
alloc::Layout,
213203
mem::align_of,
214204
ptr,
205+
sync::atomic::Ordering,
215206
task::{RawWaker, RawWakerVTable, Waker},
216207
};
217208

@@ -299,9 +290,15 @@ mod slot {
299290
// then call the stored waker to trigger a poll
300291
unsafe fn wake_by_ref(waker: *const ()) {
301292
let slot = waker.cast::<ArcSlotInner>();
302-
let index = *core::ptr::addr_of!((*slot).index);
303-
let inner = inner_ref(slot);
304-
if inner.push(index) {
293+
294+
let node = &*slot;
295+
// node.woken.store(true, Ordering::Relaxed);
296+
let prev = node.wake_lock.swap(true, Ordering::SeqCst);
297+
298+
if !prev {
299+
let index = node.index;
300+
let inner = inner_ref(slot);
301+
inner.push(index);
305302
inner.meta.waker.notify();
306303
}
307304
}
@@ -452,7 +449,7 @@ impl ArcSlice {
452449
ArcSlotInner {
453450
index: i,
454451
wake_lock: AtomicBool::new(false),
455-
woken: AtomicBool::new(false),
452+
// woken: AtomicBool::new(false),
456453
next: AtomicUsize::new(usize::MAX),
457454
},
458455
);

src/futures_unordered_bounded.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ impl<F> FuturesUnorderedBounded<F> {
206206
}
207207

208208
match unsafe { self.shared.pop() } {
209-
crate::arc_slice::ReadySlot::None => break,
209+
crate::arc_slice::ReadySlot::None => return Poll::Pending,
210210
crate::arc_slice::ReadySlot::Inconsistent => {
211211
cx.waker().wake_by_ref();
212212
return Poll::Pending;
@@ -224,8 +224,6 @@ impl<F> FuturesUnorderedBounded<F> {
224224
}
225225
}
226226
}
227-
228-
Poll::Pending
229227
}
230228
}
231229

0 commit comments

Comments
 (0)