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
use crate::sys::mutex as imp;

/// 基于 OS 的互斥锁,用于静态变量。
///
/// 此互斥锁具有 const 构造函数 ([`StaticMutex::new`]),未实现 `Drop` 来清理资源,并且在重新使用时会导致 UB。
///
///
/// 此互斥锁不会实现中毒。
///
/// 这是 `imp::Mutex` 的包装,它不 * 调用 `init()` 和 `destroy()`。
///
pub struct StaticMutex(imp::Mutex);

unsafe impl Sync for StaticMutex {}

impl StaticMutex {
    /// 创建一个新的互斥锁以供使用。
    pub const fn new() -> Self {
        Self(imp::Mutex::new())
    }

    /// 调用 raw_lock(),然后返回 RAII 防护以确保互斥锁将被解锁。
    ///
    ///
    /// 在同一线程锁定时调用此函数是未定义的行为。
    ///
    #[inline]
    pub unsafe fn lock(&'static self) -> StaticMutexGuard {
        self.0.lock();
        StaticMutexGuard(&self.0)
    }
}

#[must_use]
pub struct StaticMutexGuard(&'static imp::Mutex);

impl Drop for StaticMutexGuard {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            self.0.unlock();
        }
    }
}

/// 基于操作系统的互斥锁。
///
/// 此互斥锁没有 * const 构造函数,在 `Drop` 实现中清理其资源,可以安全地移动 (未借用时),并且在重新使用时不会导致 UB。
///
///
/// 此互斥锁不会实现中毒。
///
/// 根据平台的不同,它可以是 `Box<imp::Mutex>` 或 `imp::Mutex` 的包装。在 `imp::Mutex` 可能不会移动的平台上,它是 boxed。
///
///
///
pub struct MovableMutex(imp::MovableMutex);

unsafe impl Sync for MovableMutex {}

impl MovableMutex {
    /// 创建一个新的互斥锁。
    pub fn new() -> Self {
        let mut mutex = imp::MovableMutex::from(imp::Mutex::new());
        unsafe { mutex.init() };
        Self(mutex)
    }

    pub(super) fn raw(&self) -> &imp::Mutex {
        &self.0
    }

    /// 锁定互斥锁以阻止当前线程,直到可用为止。
    #[inline]
    pub fn raw_lock(&self) {
        unsafe { self.0.lock() }
    }

    /// 尝试不间断地锁定互斥锁,并返回是否已成功获取它。
    ///
    #[inline]
    pub fn try_lock(&self) -> bool {
        unsafe { self.0.try_lock() }
    }

    /// 解锁互斥锁。
    ///
    /// 如果当前线程实际上没有持有互斥锁,则行为是不确定的。
    ///
    #[inline]
    pub unsafe fn raw_unlock(&self) {
        self.0.unlock()
    }
}

impl Drop for MovableMutex {
    fn drop(&mut self) {
        unsafe { self.0.destroy() };
    }
}