urcu/collections/hashmap/
reference.rs1use std::marker::PhantomData;
2use std::ptr::NonNull;
3
4use crate::collections::hashmap::raw::RawNode;
5use crate::rcu::flavor::RcuFlavor;
6use crate::RcuRef;
7
8pub struct RefOwned<K, V>(Box<RawNode<K, V>>);
12
13impl<K, V> RefOwned<K, V> {
14 pub fn key(&self) -> &K {
16 &self.0.key
17 }
18
19 pub fn value(&self) -> &V {
21 &self.0.value
22 }
23}
24
25unsafe impl<K: Send, V: Send> Send for RefOwned<K, V> {}
29
30unsafe impl<K: Sync, V: Sync> Sync for RefOwned<K, V> {}
34
35pub struct Ref<K, V, F>
39where
40 K: Send + 'static,
41 V: Send + 'static,
42 F: RcuFlavor + 'static,
43{
44 ptr: *mut RawNode<K, V>,
45 _context: PhantomData<*const F>,
46}
47
48impl<K, V, F> Ref<K, V, F>
49where
50 K: Send,
51 V: Send,
52 F: RcuFlavor,
53{
54 pub(crate) fn new(ptr: NonNull<RawNode<K, V>>) -> Self {
55 Self {
56 ptr: ptr.as_ptr(),
57 _context: PhantomData,
58 }
59 }
60
61 pub fn key(&self) -> &K {
62 &unsafe { self.ptr.as_ref_unchecked() }.key
64 }
65
66 pub fn value(&self) -> &V {
67 &unsafe { self.ptr.as_ref_unchecked() }.value
69 }
70}
71
72impl<K, V, F> Drop for Ref<K, V, F>
73where
74 K: Send + 'static,
75 V: Send + 'static,
76 F: RcuFlavor + 'static,
77{
78 fn drop(&mut self) {
79 if !self.ptr.is_null() {
80 Self {
81 ptr: self.ptr,
82 _context: Default::default(),
83 }
84 .safe_cleanup();
85 }
86 }
87}
88
89unsafe impl<K, V, F> RcuRef<F> for Ref<K, V, F>
93where
94 K: Send,
95 V: Send,
96 F: RcuFlavor,
97{
98 type Output = RefOwned<K, V>;
99
100 unsafe fn take_ownership_unchecked(mut self) -> Self::Output {
101 let output = RefOwned(Box::from_raw(self.ptr));
102
103 self.ptr = std::ptr::null_mut();
105
106 output
107 }
108}
109
110unsafe impl<K, V, F> Send for Ref<K, V, F>
111where
112 K: Send,
113 V: Send,
114 F: RcuFlavor,
115{
116}