1use std::collections::{HashMap,HashSet};
18use std::hash::{Hash,Hasher};
19use std::borrow::Borrow;
20
21use parking_lot::Mutex;
22
23#[cfg(test)] mod tests;
24pub mod id;
25use id::{Id,UniqueId};
26
27#[derive(Debug)]
30pub struct GuestCell<T:?Sized> {
31 map: Mutex<HashMap<Id, *mut T>>,
32 id: UniqueId
33}
34
35impl<T:?Sized> Default for GuestCell<T> {
36 fn default()->Self {
37 GuestCell {
38 map: Mutex::new(HashMap::new()),
39 id: UniqueId::default()
40 }
41 }
42}
43
44impl<T:?Sized> GuestCell<T> {
45 pub fn new()->Self { Self::default() }
46}
47
48unsafe impl<T:?Sized + Send> Send for GuestCell<T> {}
50unsafe impl<T:?Sized + Send> Sync for GuestCell<T> {}
51
52pub unsafe trait IndirectGuestCell: Borrow<GuestCell<Self::Inner>> {
55 type Inner: ?Sized;
56}
57
58unsafe impl<T:?Sized> IndirectGuestCell for &'_ GuestCell<T> { type Inner = T; }
59unsafe impl<T:?Sized> IndirectGuestCell for std::sync::Arc<GuestCell<T>> { type Inner = T; }
60unsafe impl<T:?Sized> IndirectGuestCell for std::rc::Rc<GuestCell<T>> { type Inner = T; }
61
62trait ErasedGuestCell {
63 fn guest_drop(&self, guest: &mut UniqueId);
65
66 fn id(&self)->&UniqueId;
68
69 fn len(&self)->usize;
74}
75
76impl<T:?Sized> ErasedGuestCell for GuestCell<T> {
77 fn guest_drop(&self, guest_id: &mut UniqueId) {
78 let ptr = self.map.lock().remove(&guest_id).unwrap();
79
80 let _ = unsafe { Box::from_raw(ptr) };
83 }
84
85 fn id(&self)->&UniqueId { &self.id }
86
87 fn len(&self)->usize { self.map.lock().len() }
88}
89
90impl<Ptr:IndirectGuestCell> ErasedGuestCell for Ptr {
91 fn guest_drop(&self, guest: &mut UniqueId) {
92 self.borrow().guest_drop(guest)
93 }
94
95 fn id(&self)->&UniqueId {
96 self.borrow().id()
97 }
98
99 fn len(&self)->usize { self.borrow().len() }
100}
101
102impl PartialEq for dyn ErasedGuestCell + '_ {
103 fn eq(&self, rhs: &dyn ErasedGuestCell)->bool {
104 **self.id() == **rhs.id()
105 }
106}
107
108impl Eq for dyn ErasedGuestCell + '_ {}
109
110impl Hash for dyn ErasedGuestCell + '_ {
111 fn hash<H:Hasher>(&self, h:&mut H) {
112 self.id().hash(h);
113 }
114}
115
116#[derive(Default)]
118pub struct Guest<'a> {
119 id: UniqueId,
120 cells: HashSet<Box<dyn ErasedGuestCell + 'a>>,
121}
122
123impl Drop for Guest<'_> {
124 fn drop(&mut self) {
125 for map in &self.cells {
126 map.guest_drop(&mut self.id);
127 }
128 }
129}
130
131impl std::fmt::Debug for Guest<'_> {
132 fn fmt(&self, f:&mut std::fmt::Formatter<'_>)->Result<(), std::fmt::Error> {
133 f.debug_struct("Guest")
134 .field("id", &self.id)
135 .field("cells", &self.cells.iter().map(|x| x.id()).collect::<Vec<_>>())
136 .finish()
137 }
138}
139
140impl<'a> Guest<'a> {
141 pub fn new()->Self { Self::default() }
143
144 pub fn get<T:?Sized>(&self, cell: impl 'a + IndirectGuestCell<Inner=T>)->Option<&T> {
145 let guard = cell.borrow().map.lock();
146 let ptr:*mut T = *guard.get(&self.id)?;
147
148 Some(unsafe { &*ptr })
150 }
151
152 pub fn get_mut<T:?Sized>(&mut self, cell: impl 'a + IndirectGuestCell<Inner=T>)->Option<&mut T> {
153 let guard = cell.borrow().map.lock();
154 let ptr:*mut T = *guard.get(&self.id)?;
155
156 Some(unsafe { &mut *ptr })
158 }
159
160 pub fn get_or_init_mut<T:?Sized>(&mut self,
161 cell: impl 'a + IndirectGuestCell<Inner=T>,
162 init: impl FnOnce()->Box<T>)->&mut T {
163 let ptr:*mut T = {
164 let mut guard = cell.borrow().map.lock();
165 *guard.entry(*self.id).or_insert_with(|| Box::into_raw(init()))
166 };
167
168 self.cells.insert(Box::new(cell));
169 unsafe { &mut *ptr }
171 }
172
173 pub fn set<T:?Sized>(&mut self, cell: impl 'a + IndirectGuestCell<Inner=T>, val:Box<T>)->Option<Box<T>> {
174 let result = cell.borrow().map.lock().insert(*self.id, Box::into_raw(val));
175 self.cells.insert(Box::new(cell));
176
177 Some(unsafe { Box::from_raw(result?) })
179 }
180
181 pub fn take<T:?Sized>(&mut self, cell: impl 'a + IndirectGuestCell<Inner=T>)->Option<Box<T>> {
182 let result = cell.borrow().map.lock().remove(&self.id);
183 self.cells.remove(&cell as &dyn ErasedGuestCell);
184
185 Some(unsafe { Box::from_raw(result?) })
187 }
188}