jay-compositor 1.14.0

The Jay compositor
use {
    crate::utils::{rc_eq::rc_eq, thread_id::ThreadId, thread_local_data::ThreadLocalData},
    std::{
        rc::Rc,
        sync::atomic::{AtomicUsize, Ordering::Relaxed},
        thread,
    },
};

#[test]
fn test() {
    static RC: AtomicUsize = AtomicUsize::new(0);
    struct T;
    impl Drop for T {
        fn drop(&mut self) {
            RC.fetch_sub(1, Relaxed);
        }
    }

    assert_eq!(RC.load(Relaxed), 0);

    thread::spawn(|| {
        let data = ThreadLocalData::new(ThreadId::current());
        let get = || {
            data.get_or_create(|| {
                RC.fetch_add(1, Relaxed);
                Rc::new(T)
            })
        };
        assert_eq!(RC.load(Relaxed), 0);
        let t = get();
        assert_eq!(RC.load(Relaxed), 1);
        let t2 = get();
        assert_eq!(RC.load(Relaxed), 1);
        assert!(rc_eq(&t, &t2));
    })
    .join()
    .unwrap();

    assert_eq!(RC.load(Relaxed), 0);
}

#[test]
#[should_panic]
fn wrong_thread() {
    let data = thread::spawn(|| ThreadLocalData::new(ThreadId::current()))
        .join()
        .unwrap();
    data.get_or_create(|| Rc::new(()));
}