Skip to content

Commit 0b6127e

Browse files
committed
Use fetch_or() instead of compare_exchange() ...
... and clarify the comment about Ordering::AcqRel.
1 parent 61fc475 commit 0b6127e

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

src/lib.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,20 +248,21 @@ impl<T> RingBuffer<T> {
248248
}
249249

250250
unsafe fn abandon<T>(buffer: NonNull<RingBuffer<T>>) {
251-
// The two threads (producer and consumer) must observe the same order of accesses
252-
// to `is_abandoned`. This is accomplished with Acquire/Release.
251+
// The "store" part of `fetch_or()` has to use `Release` to make sure that any previous writes
252+
// to the ring buffer happen before it (in the thread that abandons first).
253+
// The "load" part has to use `Acquire` to make sure that reading `head` and `tail`
254+
// in the destructor happens after it (in the thread that drops the `RingBuffer`).
253255
if buffer
254256
.as_ref()
255257
.is_abandoned
256-
.compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire)
257-
.is_ok()
258+
.fetch_or(true, Ordering::AcqRel)
258259
{
259-
// The flag wasn't set before, so we are the first to abandon the RingBuffer
260-
// and it should not be dropped yet.
261-
} else {
262260
// The flag was already set, i.e. the other thread has already abandoned
263261
// the RingBuffer and it can be dropped now.
264262
drop_slow(buffer);
263+
} else {
264+
// The flag wasn't set before, so we are the first to abandon the RingBuffer
265+
// and it should not be dropped yet.
265266
}
266267
}
267268

0 commit comments

Comments
 (0)