orx_concurrent_option/raw.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
use crate::{states::*, ConcurrentOption};
use core::sync::atomic::Ordering;
impl<T> ConcurrentOption<T> {
// raw
/// Returns:
/// * a raw `*const T` pointer to the underlying data when the option is of Some variant;
/// * `None` otherwise.
///
/// See [`get_raw_with_order`] to explicitly set the ordering.
///
/// [`get_raw_with_order`]: ConcurrentOption::get_raw_with_order
///
/// # Example
///
/// ```rust
/// use orx_concurrent_option::*;
///
/// let x = ConcurrentOption::<String>::none();
/// let p = x.get_raw();
/// assert!(p.is_none());
///
/// let x = ConcurrentOption::some(3.to_string());
/// let p = x.get_raw();
/// assert!(p.is_some());
/// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
/// ```
pub fn get_raw(&self) -> Option<*const T> {
match self.spin_get_handle(SOME, SOME) {
Some(_handle) => {
let x = unsafe { &*self.value.get() };
Some(x.as_ptr())
}
None => None,
}
}
/// Returns:
/// * a raw `*mut T` pointer to the underlying data when the option is of Some variant;
/// * `None` otherwise.
///
/// See [`get_raw_mut_with_order`] to explicitly set the ordering.
///
/// [`get_raw_mut_with_order`]: ConcurrentOption::get_raw_mut_with_order
///
/// ```rust
/// use orx_concurrent_option::*;
///
/// let x = ConcurrentOption::<String>::none();
/// let p = x.get_raw_mut();
/// assert!(p.is_none());
///
/// let x = ConcurrentOption::some(3.to_string());
/// let p = x.get_raw_mut();
/// assert!(p.is_some());
/// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
///
/// let p = x.get_raw().unwrap();
/// assert_eq!(unsafe { p.as_ref() }, Some(&3.to_string()));
///
/// let p = x.get_raw_mut();
/// let p = p.unwrap();
/// let _ = unsafe { p.replace(7.to_string()) }; // only write leads to memory leak
/// assert_eq!(unsafe { x.as_ref() }, Some(&7.to_string()));
/// ```
pub fn get_raw_mut(&self) -> Option<*mut T> {
match self.spin_get_handle(SOME, SOME) {
Some(_handle) => {
let x = unsafe { &mut *self.value.get() };
Some(x.as_mut_ptr())
}
None => None,
}
}
// raw with-order
/// Returns:
/// * a raw `*const T` pointer to the underlying data when the option is of Some variant;
/// * `None` otherwise.
///
/// Depending on requirement of the use case, `Relaxed`, `Acquire` or `SeqCst` can be used as the `order`.
///
/// # Example
///
/// ```rust
/// use orx_concurrent_option::*;
/// use core::sync::atomic::Ordering;
///
/// let x = ConcurrentOption::<String>::none();
/// let p = x.get_raw_with_order(Ordering::SeqCst);
/// assert!(p.is_none());
///
/// let x = ConcurrentOption::some(3.to_string());
/// let p = x.get_raw_with_order(Ordering::Acquire);
/// assert!(p.is_some());
/// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
/// ```
pub fn get_raw_with_order(&self, order: Ordering) -> Option<*const T> {
match self.state.load(order) {
SOME => {
let x = unsafe { &*self.value.get() };
Some(x.as_ptr())
}
_ => None,
}
}
/// Returns:
/// * a raw `*mut T` pointer to the underlying data when the option is of Some variant;
/// * `None` otherwise.
///
/// Depending on requirement of the use case, `Relaxed`, `Acquire` or `SeqCst` can be used as the `order`.
///
/// ```rust
/// use orx_concurrent_option::*;
/// use core::sync::atomic::Ordering;
///
/// let x = ConcurrentOption::<String>::none();
/// let p = x.get_raw_mut_with_order(Ordering::SeqCst);
/// assert!(p.is_none());
///
/// let x = ConcurrentOption::some(3.to_string());
/// let p = x.get_raw_mut_with_order(Ordering::Acquire);
/// assert!(p.is_some());
/// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
///
/// let p = x.get_raw_mut_with_order(Ordering::Relaxed).unwrap();
/// assert_eq!(unsafe { p.as_ref() }, Some(&3.to_string()));
///
/// let p = x.get_raw_mut_with_order(Ordering::Relaxed);
/// let p = p.unwrap();
/// let _ = unsafe { p.replace(7.to_string()) }; // only write leads to memory leak
/// assert_eq!(unsafe { x.as_ref() }, Some(&7.to_string()));
/// ```
pub fn get_raw_mut_with_order(&self, order: Ordering) -> Option<*mut T> {
match self.state.load(order) {
SOME => {
let x = unsafe { &mut *self.value.get() };
Some(x.as_mut_ptr())
}
_ => None,
}
}
}