manual_rwlock/
read_gaurd.rs

1use crate::{write_gaurd::WriteGaurd, LockError, LockResult, LockState};
2use std::ops::Deref;
3
4pub struct ReadGaurd<'a, T: Sized> {
5    pub(super) state: &'a LockState,
6    pub(super) data: *mut T,
7}
8
9impl<'a, T> ReadGaurd<'a, T> {
10    ///Same as [Self::to_write] but instead of blocking thread,
11    /// if a lock can not be obtained when called a [LockError::WouldBlock] is returned
12    pub fn try_to_write(self) -> LockResult<WriteGaurd<'a, T>> {
13        self.state.try_to_write()?;
14        Ok(WriteGaurd {
15            state: &self.state,
16            data: self.data,
17        })
18    }
19
20    /// ```
21    /// use manual_rwlock::MrwLock;
22    /// let mrw_lock = MrwLock::new(10);
23    /// let read = mrw_lock.read().unwrap();
24    /// let mut write = read.to_write().unwrap();
25    /// *write = 5;
26    /// let read = write.to_read();
27    /// assert_eq!(*read, 5)
28    /// ```
29    pub fn to_write(self) -> LockResult<WriteGaurd<'a, T>> {
30        self.state.to_write()?;
31        Ok(WriteGaurd {
32            state: &self.state,
33            data: self.data,
34        })
35    }
36
37    /// Releases lock without dropping object. This can allow for a write lock to obtained and do some work after which the lock must be reobtained
38    ///# Safety
39    /// Do not access contents before reobtaining lock with either reobtain or try_reobtain
40    /// # Examples
41    ///```
42    ///  use manual_rwlock::MrwLock;
43    ///
44    /// let rwlock = MrwLock::new(5);
45    /// let read_rw = rwlock.read().unwrap();
46    /// unsafe { read_rw.early_release() };
47    /// {
48    ///     let mut write = rwlock.write().unwrap();
49    ///     *write += 5;
50    /// }
51    /// unsafe { read_rw.reobtain().unwrap() };
52    /// assert_eq!(*read_rw, 10);
53    ///
54    ///```
55    ///
56    pub unsafe fn early_release(&self) {
57        self.state.drop_read();
58    }
59
60    /// block until lock can be reobtained
61    /// # Safety
62    /// do not use unless early release has been called. Only call at most once after each early release
63    pub unsafe fn reobtain(&self) -> Result<(), LockError> {
64        self.state.read()?;
65        Ok(())
66    }
67
68    /// attempt to reobtain lock, if not possible at this time return `LockError:WouldBlock`
69    /// # Safety
70    /// do not use unless early release has been called. Only call at most once after each early release
71    pub unsafe fn try_reobtain(&self) -> Result<(), LockError> {
72        self.state.try_read()?;
73        Ok(())
74    }
75}
76
77impl<'a, T> Drop for ReadGaurd<'a, T> {
78    fn drop(&mut self) {
79        self.state.drop_read();
80    }
81}
82
83impl<'a, T> Deref for ReadGaurd<'a, T> {
84    type Target = T;
85
86    fn deref(&self) -> &Self::Target {
87        unsafe { &*self.data }
88    }
89}
90
91///
92/// ```
93///  use manual_rwlock::MrwLock;
94///
95/// let rwlock = MrwLock::new(5);
96/// let read = rwlock.read().unwrap();
97/// let read2 = read.clone();
98/// assert_eq!(*read2, 5);
99///
100/// ```
101impl<'a, T> Clone for ReadGaurd<'a, T> {
102    fn clone(&self) -> Self {
103        self.state.read().unwrap();
104        Self {
105            state: self.state,
106            data: self.data,
107        }
108    }
109}
110
111
112
113unsafe impl<'a,T> Send for ReadGaurd<'a, T>{}
114unsafe impl<'a, T> Sync for ReadGaurd<'a, T>{}