hipthread 0.1.3

no-std thread library based on pthread
Documentation
use super::pthread;
use core::cell::UnsafeCell;
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};

/// 封装pthread_mutex_t提供互斥锁机制.
pub struct Mutex<T: ?Sized> {
    lock: pthread::pthread_mutex_t,
    val: UnsafeCell<T>,
}

unsafe impl<T: Send + ?Sized> Send for Mutex<T> {}
unsafe impl<T: ?Sized> Sync for Mutex<T> {}

pub struct MutexGuard<'a, T: ?Sized + 'a> {
    mutex: &'a Mutex<T>,
    // impl !Send for MutexGuard
    // impl !Sync for MutexGuard
    mark: PhantomData<*const T>,
}

unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}

impl<T: ?Sized> Drop for Mutex<T> {
    fn drop(&mut self) {
        unsafe {
            pthread::pthread_mutex_destroy(&mut self.lock);
        }
    }
}

impl<T> Mutex<T> {
    pub const fn new(val: T) -> Self {
        Self {
            lock: pthread::PTHREAD_MUTEX_INITIALIZER,
            val: UnsafeCell::new(val),
        }
    }
}

impl<T: ?Sized> Mutex<T> {
    fn get_lock(&self) -> *mut pthread::pthread_mutex_t {
        &self.lock as *const _ as *mut pthread::pthread_mutex_t
    }
    pub fn lock(&self) -> MutexGuard<'_, T> {
        let ret = unsafe { pthread::pthread_mutex_lock(self.get_lock()) };
        assert_eq!(ret, 0);
        MutexGuard::new(self)
    }

    pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
        let ret = unsafe { pthread::pthread_mutex_trylock(self.get_lock()) };
        if ret == 0 {
            Some(MutexGuard::new(self))
        } else {
            None
        }
    }
}

impl<'a, T: ?Sized> MutexGuard<'a, T> {
    fn new(mutex: &'a Mutex<T>) -> Self {
        Self {
            mutex,
            mark: PhantomData,
        }
    }
}

impl<T: ?Sized> Drop for MutexGuard<'_, T> {
    fn drop(&mut self) {
        unsafe {
            pthread::pthread_mutex_unlock(self.mutex.get_lock());
        }
    }
}

impl<T: ?Sized> Deref for MutexGuard<'_, T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.mutex.val.get() }
    }
}

impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.mutex.val.get() }
    }
}

#[cfg(test)]
mod test {
    use crate::*;
    use hipool::*;

    #[test]
    fn test_mutex() {
        let lock = Arc::new(Mutex::new(1)).unwrap();
        let cloned = lock.clone();
        let mut val = lock.lock();
        let handle = spawn(move || {
            let val = cloned.lock();
            *val
        })
        .unwrap();
        *val = 100;
        core::mem::drop(val);
        let val = handle.join().unwrap();
        assert_eq!(val, 100);
    }
}