blob: cd626faee9ad26bb3969b6e9b9018ce3de97d658 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
//! # Synchronization module
//!
//! Provides synchronization objects for thread-safe memory sharing.
use core::cell::UnsafeCell;
/// # Synchronization interfaces
///
/// Provides Synchronization traits.
pub mod interface {
/// # Mutex Trait
///
/// Basic Locking primitive to allow single-process access to data
pub trait Mutex {
/// # The data
///
/// Each mutex protects some internal data from modification across
/// processes when it is in use. This is important if the process
/// is preempted while the function is using it.
type Data;
/// # Locking mechanism
///
/// Locks the mutex to access the data in a closure.
/// The data can be read and modified in this closure without worry
/// of poisoning the data across processes.
fn lock<'a, R>(&'a self, f: impl FnOnce(&'a mut Self::Data) -> R) -> R;
}
}
/// # Basic Lock Structure
pub struct NullLock<T> where T: ?Sized {
/// The internal data to safely share
data: UnsafeCell<T>,
}
/// # Allow thread sharing
unsafe impl<T> Send for NullLock<T> where T: ?Sized + Send {}
/// # Allow thread sharing
unsafe impl<T> Sync for NullLock<T> where T: ?Sized + Send {}
impl<T> NullLock<T> {
/// # Create a new instance of the lock
pub const fn new(data: T) -> Self {
Self {
data: UnsafeCell::new(data),
}
}
}
impl<T> interface::Mutex for NullLock<T> {
/// # Underlying data of the lock
type Data = T;
/// # Locking mechanism
///
/// Locks the Mutex, and passes a mutable reference
/// to the encapsulated data to a closure.
fn lock<'a, R>(&'a self, f: impl FnOnce(&'a mut T) -> R) -> R {
let data = unsafe { &mut *self.data.get() };
f(data)
}
}
|