1use crate::rcu_ptr::{RcuPtr, RcuReadGuard};
6use crate::rcu_read_scope::RcuReadScope;
7use crate::state_machine::rcu_drop;
8
9#[derive(Debug)]
14pub struct RcuBox<T: Send + Sync + 'static> {
15 ptr: RcuPtr<T>,
16}
17
18impl<T: Send + Sync + 'static> RcuBox<T> {
19 pub fn new(data: T) -> Self {
21 Self::from(Box::new(data))
22 }
23
24 pub fn read(&self) -> RcuReadGuard<T> {
29 self.ptr.get()
30 }
31
32 pub fn as_ref<'a>(&self, scope: &'a RcuReadScope) -> &'a T {
37 self.ptr.read(scope).as_ref().unwrap()
38 }
39
40 pub fn update(&self, data: T) {
45 let ptr = Box::into_raw(Box::new(data));
46 unsafe { self.replace(ptr) };
48 }
49
50 unsafe fn replace(&self, ptr: *mut T) {
56 let old_ptr = self.ptr.replace(ptr);
57 let object = unsafe { Box::from_raw(old_ptr) };
58 rcu_drop(object);
59 }
60}
61
62impl<T: Clone + Send + Sync + 'static> RcuBox<T> {
63 pub fn cloned(&self) -> T {
67 self.as_ref(&RcuReadScope::new()).clone()
68 }
69}
70
71impl<T: Send + Sync + 'static> Drop for RcuBox<T> {
72 fn drop(&mut self) {
73 unsafe { self.replace(std::ptr::null_mut()) };
75 }
76}
77
78impl<T: Default + Send + Sync + 'static> Default for RcuBox<T> {
79 fn default() -> Self {
80 Self::new(T::default())
81 }
82}
83
84impl<T: Clone + Send + Sync + 'static> Clone for RcuBox<T> {
85 fn clone(&self) -> Self {
86 let value = self.read();
87 Self::new(value.clone())
88 }
89}
90
91impl<T: Send + Sync + 'static> From<Box<T>> for RcuBox<T> {
92 fn from(value: Box<T>) -> Self {
93 Self { ptr: RcuPtr::new(Box::into_raw(value)) }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use crate::state_machine::rcu_synchronize;
101 use std::ops::Deref;
102
103 #[test]
104 fn test_rcu_cell() {
105 let value = RcuBox::new(42);
106 assert_eq!(value.read().deref(), &42);
107 }
108
109 #[test]
110 fn test_rcu_cell_set_deferred() {
111 let value = RcuBox::new(42);
112 value.update(43);
113 assert_eq!(value.read().deref(), &43);
114 rcu_synchronize();
115 }
116
117 #[test]
118 fn test_rcu_cell_drop() {
119 let value = RcuBox::new(42);
120 drop(value);
121 }
122}