im/
sync.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5pub(crate) use self::lock::Lock;
6
7#[cfg(threadsafe)]
8mod lock {
9    use std::sync::{Arc, Mutex, MutexGuard};
10
11    /// Thread safe lock: just wraps a `Mutex`.
12    pub(crate) struct Lock<A> {
13        lock: Arc<Mutex<A>>,
14    }
15
16    impl<A> Lock<A> {
17        pub(crate) fn new(value: A) -> Self {
18            Lock {
19                lock: Arc::new(Mutex::new(value)),
20            }
21        }
22
23        #[inline]
24        pub(crate) fn lock(&mut self) -> Option<MutexGuard<'_, A>> {
25            self.lock.lock().ok()
26        }
27    }
28
29    impl<A> Clone for Lock<A> {
30        fn clone(&self) -> Self {
31            Lock {
32                lock: self.lock.clone(),
33            }
34        }
35    }
36}
37
38#[cfg(not(threadsafe))]
39mod lock {
40    use std::cell::{RefCell, RefMut};
41    use std::rc::Rc;
42
43    /// Single threaded lock: a `RefCell` so we should safely panic if somehow
44    /// trying to access the stored data twice from the same thread.
45    pub(crate) struct Lock<A> {
46        lock: Rc<RefCell<A>>,
47    }
48
49    impl<A> Lock<A> {
50        pub(crate) fn new(value: A) -> Self {
51            Lock {
52                lock: Rc::new(RefCell::new(value)),
53            }
54        }
55
56        #[inline]
57        pub(crate) fn lock(&mut self) -> Option<RefMut<'_, A>> {
58            self.lock.try_borrow_mut().ok()
59        }
60    }
61
62    impl<A> Clone for Lock<A> {
63        fn clone(&self) -> Self {
64            Lock {
65                lock: self.lock.clone(),
66            }
67        }
68    }
69}