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>{}