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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;

use crate::cell::UnsafeCell;
use crate::ops::Deref;
use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use crate::sys::locks as sys;

/// 可重入互斥
///
/// 此互斥锁将阻止 *其他* 线程,等待该锁可用。已经锁定互斥锁的线程可以多次将其锁定而不会阻塞,从而避免了常见的死锁源。
///
/// 这是由 stdout().lock() 和朋友使用的。
///
/// ## 实现细节
///
/// 'owner' 字段跟踪哪个线程锁定了互斥锁。
///
/// 我们使用 current_thread_unique_ptr() 作为线程标识符,它只是一个线程局部变量的地址。
///
/// 如果 `owner` 设置为当前线程的标识符,我们假设互斥锁已经被锁定,而不是再次锁定它,我们增加 `lock_count`。
///
/// 解锁时,我们将 `lock_count` 递减,互斥锁达到 0 时才解锁。
///
/// `lock_count` 受互斥锁保护,只有锁定了互斥锁的线程才能访问,所以不需要同步。
///
/// `owner` 可以被其他想要查看它们是否已经持有锁的线程检查,因此需要是原子的。如果比较相等,我们就在持有互斥锁的同一个线程上,并且内存访问可以使用宽松的排序,因为我们不处理多个线程。
///
/// 如果不相等,则将同步留给互连锁,在所有情况下都可以对 `owner` 字段进行宽松的内存排序。
///
///
///
///
///
///
///
///
///
///
pub struct ReentrantMutex<T> {
    mutex: sys::Mutex,
    owner: AtomicUsize,
    lock_count: UnsafeCell<u32>,
    data: T,
}

unsafe impl<T: Send> Send for ReentrantMutex<T> {}
unsafe impl<T: Send> Sync for ReentrantMutex<T> {}

impl<T> UnwindSafe for ReentrantMutex<T> {}
impl<T> RefUnwindSafe for ReentrantMutex<T> {}

/// 互斥锁的 "scoped lock" 的 RAII 实现。当此结构体被丢弃 (离开作用域) 时,这个锁将被解锁。
///
/// 可以通过此保护程序的 Deref 实现访问由互斥锁保护的数据。
///
/// # Mutability
///
/// 与 `MutexGuard` 不同,`ReentrantMutexGuard` 不实现 `DerefMut`,因为实现 trait 会违反 Rust 的引用别名规则。
/// 使用内部可变性 (通常为 `RefCell`) 以更改受保护的数据。
///
///
///
///
#[must_use = "if unused the ReentrantMutex will immediately unlock"]
pub struct ReentrantMutexGuard<'a, T: 'a> {
    lock: &'a ReentrantMutex<T>,
}

impl<T> !Send for ReentrantMutexGuard<'_, T> {}

impl<T> ReentrantMutex<T> {
    /// 在解锁状态下创建一个新的可重入互斥锁。
    pub const fn new(t: T) -> ReentrantMutex<T> {
        ReentrantMutex {
            mutex: sys::Mutex::new(),
            owner: AtomicUsize::new(0),
            lock_count: UnsafeCell::new(0),
            data: t,
        }
    }

    /// 获取一个互斥锁,阻塞当前线程,直到能够这样做为止。
    ///
    /// 此函数将阻止调用者,直到可以获取互斥锁为止。
    /// 返回时,该线程是唯一具有互斥锁的线程。
    /// 当调用此方法的线程已持有锁时,调用将成功而不会阻塞。
    ///
    /// # Errors
    ///
    /// 如果此互斥锁的另一个用户在持有互斥锁时 panic,那么如果以其他方式获取互斥锁,则此调用将返回失败。
    ///
    ///
    ///
    pub fn lock(&self) -> ReentrantMutexGuard<'_, T> {
        let this_thread = current_thread_unique_ptr();
        // 安全性: 我们只有在拥有锁的时候才接触 lock_count。
        unsafe {
            if self.owner.load(Relaxed) == this_thread {
                self.increment_lock_count();
            } else {
                self.mutex.lock();
                self.owner.store(this_thread, Relaxed);
                debug_assert_eq!(*self.lock_count.get(), 0);
                *self.lock_count.get() = 1;
            }
        }
        ReentrantMutexGuard { lock: self }
    }

    /// 尝试获取此锁。
    ///
    /// 如果此时无法获取锁,则返回 `Err`。
    /// 否则,将返回 RAII 守卫。
    ///
    /// 该函数不会阻止。
    ///
    /// # Errors
    ///
    /// 如果此互斥锁的另一个用户在持有互斥锁时 panic,那么如果以其他方式获取互斥锁,则此调用将返回失败。
    ///
    ///
    pub fn try_lock(&self) -> Option<ReentrantMutexGuard<'_, T>> {
        let this_thread = current_thread_unique_ptr();
        // 安全性: 我们只有在拥有锁的时候才接触 lock_count。
        unsafe {
            if self.owner.load(Relaxed) == this_thread {
                self.increment_lock_count();
                Some(ReentrantMutexGuard { lock: self })
            } else if self.mutex.try_lock() {
                self.owner.store(this_thread, Relaxed);
                debug_assert_eq!(*self.lock_count.get(), 0);
                *self.lock_count.get() = 1;
                Some(ReentrantMutexGuard { lock: self })
            } else {
                None
            }
        }
    }

    unsafe fn increment_lock_count(&self) {
        *self.lock_count.get() = (*self.lock_count.get())
            .checked_add(1)
            .expect("lock count overflow in reentrant mutex");
    }
}

impl<T> Deref for ReentrantMutexGuard<'_, T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.lock.data
    }
}

impl<T> Drop for ReentrantMutexGuard<'_, T> {
    #[inline]
    fn drop(&mut self) {
        // 安全性: 我们拥有这个锁。
        unsafe {
            *self.lock.lock_count.get() -= 1;
            if *self.lock.lock_count.get() == 0 {
                self.lock.owner.store(0, Relaxed);
                self.lock.mutex.unlock();
            }
        }
    }
}

/// 获取每个正在运行的线程的唯一地址。
///
/// 这可以用作非空的 usize 大小的 ID。
pub fn current_thread_unique_ptr() -> usize {
    // 使用非丢弃类型来确保它在线程销毁期间仍然可用。
    thread_local! { static X: u8 = const { 0 } }
    X.with(|x| <*const _>::addr(x))
}