Realtime safe, waitfree, concurrency library

cleanup

Changed files
+13 -20
src
+10 -18
src/lib.rs
··· 49 49 50 50 /// this function never blocks. (`fetch_update` loop doesn't count) 51 51 pub fn lock(&mut self) -> ReadGuard<'_, T> { 52 - let shared_ref = self.shared_ref(); 53 - 52 + // SAFETY: value just locked 53 + let value = unsafe { &*self.shared_ref().lock_read().get() }; 54 54 ReadGuard { 55 - shared: shared_ref, 56 - value: shared_ref.lock_read(), 57 - reader: PhantomData, 55 + value, 56 + reader: self, 58 57 } 59 58 } 60 59 } ··· 75 74 /// Doesn't implement Clone as that would require refcounting to know when to unlock. 76 75 #[derive(Debug)] 77 76 pub struct ReadGuard<'a, T> { 78 - shared: &'a Shared<T>, 79 - value: Ptr, 80 - /// `PhantomData` makes the borrow checker prove that there only ever is one `ReadGuard`. 81 - /// This allows resetting the readstate without some kind of counter 82 - reader: PhantomData<&'a mut Reader<T>>, 77 + reader: &'a Reader<T>, 78 + value: &'a T, 83 79 } 84 80 85 81 impl<T> Deref for ReadGuard<'_, T> { 86 82 type Target = T; 87 83 88 84 fn deref(&self) -> &Self::Target { 89 - // SAFETY: ReadGuard was created, so the Writer knows not to write in this spot 90 - unsafe { self.shared.get_value_ref(self.value) } 85 + self.value 91 86 } 92 87 } 93 88 ··· 101 96 } 102 97 } 103 98 104 - // /// SAFETY: behaves like a ref to T. https://doc.rust-lang.org/std/marker/trait.Sync.html 105 - // unsafe impl<T: Sync> Send for ReadGuard<'_, T> {} 106 - // /// SAFETY: behaves like a ref to T. https://doc.rust-lang.org/std/marker/trait.Sync.html 107 - // unsafe impl<T: Sync> Sync for ReadGuard<'_, T> {} 108 - 109 99 impl<T> Drop for ReadGuard<'_, T> { 110 100 fn drop(&mut self) { 111 101 // release the read lock 112 - self.shared.release_read_lock(); 102 + self.reader.shared_ref().release_read_lock(); 113 103 } 114 104 } 115 105 ··· 250 240 /// Dropping this makes all changes available to the Reader. 251 241 #[derive(Debug)] 252 242 pub struct WriteGuard<'a, T, O> { 243 + // can't hold a mut ref to T, as then it wouldn't be possible to write to both at the same time, 244 + // which is an optimization i want to keep. 253 245 writer: &'a mut Writer<T, O>, 254 246 } 255 247
+3 -2
src/shared.rs
··· 115 115 } 116 116 117 117 impl<T> Shared<T> { 118 - pub(crate) fn lock_read(&self) -> Ptr { 118 + pub(crate) fn lock_read(&self) -> &UnsafeCell<T> { 119 119 // fetch update loop could be replaced with: 120 120 // - set read state to both 121 121 // - read read ptr ··· 131 131 // SAFETY: fetch_update closure always returns Some, so the result is alwyays Ok 132 132 let result = unsafe { result.unwrap_unchecked() }; 133 133 // result is the previous value, so the read_state isn't set, only the read_ptr 134 - State::new(result).read_ptr() 134 + let ptr = State::new(result).read_ptr(); 135 + self.get_value(ptr) 135 136 } 136 137 137 138 pub(crate) fn release_read_lock(&self) {