orx_concurrent_option/
mut_handle.rs1use crate::{ConcurrentOption, states::*};
2use core::{
3 cell::UnsafeCell,
4 mem::MaybeUninit,
5 sync::atomic::{AtomicU8, Ordering},
6};
7
8pub struct MutHandle<'a, T> {
10 state: &'a AtomicU8,
11 success_state: StateU8,
12 pub value: &'a UnsafeCell<MaybeUninit<T>>,
14}
15
16impl<'a, T> MutHandle<'a, T> {
17 pub(crate) fn spin_get(
18 option: &'a ConcurrentOption<T>,
19 initial_state: StateU8,
20 success_state: StateU8,
21 ) -> Option<Self> {
22 loop {
23 match option.state.compare_exchange(
24 initial_state,
25 RESERVED,
26 Ordering::Acquire,
27 Ordering::Relaxed,
28 ) {
29 Ok(_) => {
30 return Some(Self {
31 state: &option.state,
32 success_state,
33 value: &option.value,
34 });
35 }
36 Err(previous_state) => match previous_state {
37 RESERVED => continue,
38 _ => return None,
39 },
40 }
41 }
42 }
43
44 #[allow(clippy::mut_from_ref)]
52 pub unsafe fn get_mut(&self) -> &mut T {
53 let x = unsafe { &mut *self.value.get() };
54 unsafe { MaybeUninit::assume_init_mut(x) }
55 }
56}
57
58impl<T> Drop for MutHandle<'_, T> {
59 fn drop(&mut self) {
60 self.state
61 .compare_exchange(
62 RESERVED,
63 self.success_state,
64 Ordering::Release,
65 Ordering::Relaxed,
66 )
67 .expect("Failed to update the concurrent state after concurrent state mutation");
68 }
69}