Merge fetch_and andthe prev_value check
cc https://github.com/smol-rs/concurrent-queue/pull/58#discussion_r1574686897 Signed-off-by: John Nunley <dev@notgull.net>
This commit is contained in:
parent
05e7bff8e5
commit
5b74dc8acc
|
@ -65,23 +65,27 @@ impl<T> Single<T> {
|
|||
}
|
||||
|
||||
if prev == state {
|
||||
// Swap out the value.
|
||||
// SAFETY: We have locked the state.
|
||||
let prev_value = unsafe {
|
||||
self.slot
|
||||
.with_mut(move |slot| ptr::replace(slot, MaybeUninit::new(value)))
|
||||
// If the value was pushed, swap out the value.
|
||||
let prev_value = if prev & PUSHED == 0 {
|
||||
// SAFETY: write is safe because we have locked the state.
|
||||
self.slot.with_mut(|slot| unsafe {
|
||||
slot.write(MaybeUninit::new(value));
|
||||
});
|
||||
None
|
||||
} else {
|
||||
// SAFETY: replace is safe because we have locked the state, and
|
||||
// assume_init is safe because we have checked that the value was pushed.
|
||||
let prev_value = unsafe {
|
||||
self.slot.with_mut(move |slot| {
|
||||
ptr::replace(slot, MaybeUninit::new(value)).assume_init()
|
||||
})
|
||||
};
|
||||
Some(prev_value)
|
||||
};
|
||||
|
||||
// We can unlock the slot now.
|
||||
self.state.fetch_and(!LOCKED, Ordering::Release);
|
||||
|
||||
// If the value was pushed, initialize it and return it.
|
||||
let prev_value = if prev & PUSHED == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { prev_value.assume_init() })
|
||||
};
|
||||
|
||||
// Return the old value.
|
||||
return Ok(prev_value);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue