···49495050 /// this function never blocks. (`fetch_update` loop doesn't count)
5151 pub fn lock(&mut self) -> ReadGuard<'_, T> {
5252- let shared_ref = self.shared_ref();
5353-5252+ // SAFETY: value just locked
5353+ let value = unsafe { &*self.shared_ref().lock_read().get() };
5454 ReadGuard {
5555- shared: shared_ref,
5656- value: shared_ref.lock_read(),
5757- reader: PhantomData,
5555+ value,
5656+ reader: self,
5857 }
5958 }
6059}
···7574/// Doesn't implement Clone as that would require refcounting to know when to unlock.
7675#[derive(Debug)]
7776pub struct ReadGuard<'a, T> {
7878- shared: &'a Shared<T>,
7979- value: Ptr,
8080- /// `PhantomData` makes the borrow checker prove that there only ever is one `ReadGuard`.
8181- /// This allows resetting the readstate without some kind of counter
8282- reader: PhantomData<&'a mut Reader<T>>,
7777+ reader: &'a Reader<T>,
7878+ value: &'a T,
8379}
84808581impl<T> Deref for ReadGuard<'_, T> {
8682 type Target = T;
87838884 fn deref(&self) -> &Self::Target {
8989- // SAFETY: ReadGuard was created, so the Writer knows not to write in this spot
9090- unsafe { self.shared.get_value_ref(self.value) }
8585+ self.value
9186 }
9287}
9388···10196 }
10297}
10398104104-// /// SAFETY: behaves like a ref to T. https://doc.rust-lang.org/std/marker/trait.Sync.html
105105-// unsafe impl<T: Sync> Send for ReadGuard<'_, T> {}
106106-// /// SAFETY: behaves like a ref to T. https://doc.rust-lang.org/std/marker/trait.Sync.html
107107-// unsafe impl<T: Sync> Sync for ReadGuard<'_, T> {}
108108-10999impl<T> Drop for ReadGuard<'_, T> {
110100 fn drop(&mut self) {
111101 // release the read lock
112112- self.shared.release_read_lock();
102102+ self.reader.shared_ref().release_read_lock();
113103 }
114104}
115105···250240/// Dropping this makes all changes available to the Reader.
251241#[derive(Debug)]
252242pub struct WriteGuard<'a, T, O> {
243243+ // can't hold a mut ref to T, as then it wouldn't be possible to write to both at the same time,
244244+ // which is an optimization i want to keep.
253245 writer: &'a mut Writer<T, O>,
254246}
255247
+3-2
src/shared.rs
···115115}
116116117117impl<T> Shared<T> {
118118- pub(crate) fn lock_read(&self) -> Ptr {
118118+ pub(crate) fn lock_read(&self) -> &UnsafeCell<T> {
119119 // fetch update loop could be replaced with:
120120 // - set read state to both
121121 // - read read ptr
···131131 // SAFETY: fetch_update closure always returns Some, so the result is alwyays Ok
132132 let result = unsafe { result.unwrap_unchecked() };
133133 // result is the previous value, so the read_state isn't set, only the read_ptr
134134- State::new(result).read_ptr()
134134+ let ptr = State::new(result).read_ptr();
135135+ self.get_value(ptr)
135136 }
136137137138 pub(crate) fn release_read_lock(&self) {