sublock/sync/
prooflock.rs1use std::cell::{ UnsafeCell };
5use std::marker::PhantomData;
6use std::sync::{ LockResult, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockResult };
7
8pub trait ProofBorrow<P, T> {
10 fn borrow<'a>(&'a self, proof: &P) -> &'a T;
11}
12
13
14pub trait ProofBorrowMut<P, T> {
16 fn borrow_mut<'a>(&'a self, proof: &P) -> &'a mut T;
17}
18
19pub struct SubCell<T> {
20 cell: UnsafeCell<T>,
21
22 owner_key: usize,
24}
25
26impl<T> SubCell<T> {
27 pub fn new<'a>(proof: &ProofMut<'a>, value: T) -> Self {
28 SubCell {
29 cell: UnsafeCell::new(value),
30 owner_key: proof.0,
31 }
32 }
33}
34
35impl<'b, T> ProofBorrow<Proof<'b>, T> for SubCell<T> {
36 fn borrow<'a>(&'a self, proof: &Proof<'b>) -> &'a T {
37 assert_eq!(self.owner_key, proof.0);
38 unsafe { &*self.cell.get() }
39 }
40}
41
42impl<'b, T> ProofBorrow<ProofMut<'b>, T> for SubCell<T> {
43 fn borrow<'a>(&'a self, proof: &ProofMut<'b>) -> &'a T {
44 assert_eq!(self.owner_key, proof.0);
45 unsafe { &*self.cell.get() }
46 }
47}
48
49impl<'b, T> ProofBorrowMut<ProofMut<'b>, T> for SubCell<T> {
50 fn borrow_mut<'a>(&'a self, proof: &ProofMut<'b>) -> &'a mut T {
51 assert_eq!(self.owner_key, proof.0);
52 unsafe { &mut *self.cell.get() }
53 }
54}
55
56unsafe impl<T> Send for SubCell<T> where T: Send + Sync { }
58
59unsafe impl<T> Sync for SubCell<T> where T: Send + Sync { }
61
62pub struct Proof<'a>(usize, PhantomData<&'a()>);
65
66pub struct ProofMut<'a>(usize, PhantomData<&'a()>);
69
70pub type ReadGuard<'a, T> = (Proof<'a>, RwLockReadGuard<'a, T>);
71pub type WriteGuard<'a, T> = (ProofMut<'a>, RwLockWriteGuard<'a, T>);
72
73pub struct MainLock<T> {
124 lock: RwLock<T>,
125 ownership: usize,
126}
127impl<T> MainLock<T> {
128 pub fn new(value: T) -> Self {
129 use std::mem;
130 let ownership : usize = unsafe { mem::transmute(&value as *const T) };
131 MainLock {
132 lock: RwLock::new(value),
133 ownership: ownership
134 }
135 }
136
137 pub fn read(&self) -> LockResult<ReadGuard<T>> {
139 let proof = Proof(self.ownership, PhantomData);
140 match self.lock.read() {
141 Ok(ok) => Ok((proof, ok)),
142 Err(err) => Err(PoisonError::new((proof, err.into_inner())))
143 }
144 }
145
146 pub fn try_read(&self) -> TryLockResult<ReadGuard<T>> {
148 use std::sync::TryLockError::*;
149 let proof = Proof(self.ownership, PhantomData);
150 match self.lock.try_read() {
151 Ok(ok) => Ok((proof, ok)),
152 Err(WouldBlock) => Err(WouldBlock),
153 Err(Poisoned(err)) => Err(Poisoned(PoisonError::new((proof, err.into_inner()))))
154 }
155 }
156
157 pub fn write(&self) -> LockResult<WriteGuard<T>> {
159 let proof = ProofMut(self.ownership, PhantomData);
160 match self.lock.write() {
161 Ok(ok) => Ok((proof, ok)),
162 Err(err) => Err(PoisonError::new((proof, err.into_inner())))
163 }
164 }
165
166 pub fn try_write(&self) -> TryLockResult<WriteGuard<T>> {
168 use std::sync::TryLockError::*;
169 let proof = ProofMut(self.ownership, PhantomData);
170 match self.lock.try_write() {
171 Ok(ok) => Ok((proof, ok)),
172 Err(WouldBlock) => Err(WouldBlock),
173 Err(Poisoned(err)) => Err(Poisoned(PoisonError::new((proof, err.into_inner()))))
174 }
175 }
176}
177