Skip to content

Commit

Permalink
Merge fetch_and andthe prev_value check
Browse files Browse the repository at this point in the history
cc #58 (comment)

Signed-off-by: John Nunley <dev@notgull.net>
  • Loading branch information
notgull committed Apr 26, 2024
1 parent 05e7bff commit 5b74dc8
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions src/single.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
};

// We can unlock the slot now.
self.state.fetch_and(!LOCKED, Ordering::Release);

// If the value was pushed, initialize it and return it.
// 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 {
Some(unsafe { prev_value.assume_init() })
// 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);

// Return the old value.
return Ok(prev_value);
}
Expand Down

0 comments on commit 5b74dc8

Please sign in to comment.