diem_infallible/
rwlock.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8use std::sync::RwLock as StdRwLock;
9
10pub use std::sync::{RwLockReadGuard, RwLockWriteGuard};
11
12/// A simple wrapper around the lock() function of a std::sync::RwLock
13/// The only difference is that you don't need to call unwrap() on it.
14#[derive(Debug, Default)]
15pub struct RwLock<T>(StdRwLock<T>);
16
17impl<T> RwLock<T> {
18    /// creates a read-write lock
19    pub fn new(t: T) -> Self { Self(StdRwLock::new(t)) }
20
21    /// lock the rwlock in read mode
22    pub fn read(&self) -> RwLockReadGuard<'_, T> {
23        self.0
24            .read()
25            .expect("diem cannot currently handle a poisoned lock")
26    }
27
28    /// lock the rwlock in write mode
29    pub fn write(&self) -> RwLockWriteGuard<'_, T> {
30        self.0
31            .write()
32            .expect("diem cannot currently handle a poisoned lock")
33    }
34
35    /// return the owned type consuming the lock
36    pub fn into_inner(self) -> T {
37        self.0
38            .into_inner()
39            .expect("diem cannot currently handle a poisoned lock")
40    }
41}
42
43#[cfg(test)]
44mod tests {
45
46    use super::*;
47    use std::{sync::Arc, thread};
48
49    #[test]
50    fn test_diem_rwlock() {
51        let a = 7u8;
52        let rwlock = Arc::new(RwLock::new(a));
53        let rwlock2 = rwlock.clone();
54        let rwlock3 = rwlock.clone();
55
56        let thread1 = thread::spawn(move || {
57            let mut b = rwlock2.write();
58            *b = 8;
59        });
60        let thread2 = thread::spawn(move || {
61            let mut b = rwlock3.write();
62            *b = 9;
63        });
64
65        let _ = thread1.join();
66        let _ = thread2.join();
67
68        let _read = rwlock.read();
69    }
70}