Skip to main content

maolan_engine/
mutex.rs

1use std::cell::UnsafeCell;
2
3#[derive(Debug)]
4pub struct UnsafeMutex<T> {
5    data: UnsafeCell<T>,
6}
7
8impl<T> UnsafeMutex<T> {
9    pub fn new(data: T) -> Self {
10        UnsafeMutex {
11            data: UnsafeCell::new(data),
12        }
13    }
14
15    #[allow(clippy::mut_from_ref)]
16    pub fn lock(&self) -> &mut T {
17        unsafe { &mut *self.data.get() }
18    }
19}
20
21unsafe impl<T: Send> Send for UnsafeMutex<T> {}
22unsafe impl<T: Send> Sync for UnsafeMutex<T> {}
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27
28    #[test]
29    fn new_creates_mutex_with_data() {
30        let mutex = UnsafeMutex::new(42);
31        assert_eq!(*mutex.lock(), 42);
32    }
33
34    #[test]
35    fn lock_returns_mutable_reference() {
36        let mutex = UnsafeMutex::new(String::from("hello"));
37        let data = mutex.lock();
38        data.push_str(" world");
39        assert_eq!(mutex.lock().as_str(), "hello world");
40    }
41
42    #[test]
43    fn debug_format_shows_type_name() {
44        let mutex = UnsafeMutex::new(42);
45        let debug_str = format!("{:?}", mutex);
46        assert!(debug_str.contains("UnsafeMutex"));
47    }
48
49    #[test]
50    fn send_trait_is_implemented() {
51        fn assert_send<T: Send>() {}
52        assert_send::<UnsafeMutex<i32>>();
53    }
54
55    #[test]
56    fn sync_trait_is_implemented() {
57        fn assert_sync<T: Sync>() {}
58        assert_sync::<UnsafeMutex<i32>>();
59    }
60
61    #[test]
62    fn multiple_locks_return_same_data() {
63        let mutex = UnsafeMutex::new(vec![1, 2, 3]);
64        mutex.lock().push(4);
65        assert_eq!(mutex.lock().len(), 4);
66        mutex.lock().pop();
67        assert_eq!(mutex.lock().len(), 3);
68    }
69}