blob: c95f383fb90e3cbc88a0567c779852c289c7a876 [file] [log] [blame]
use super::StaticKey;
use crate::ptr;
#[test]
fn smoke() {
static K1: StaticKey = StaticKey::new(None);
static K2: StaticKey = StaticKey::new(None);
unsafe {
assert!(K1.get().is_null());
assert!(K2.get().is_null());
K1.set(ptr::invalid_mut(1));
K2.set(ptr::invalid_mut(2));
assert_eq!(K1.get() as usize, 1);
assert_eq!(K2.get() as usize, 2);
}
}
#[test]
fn destructors() {
use crate::mem::ManuallyDrop;
use crate::sync::Arc;
use crate::thread;
unsafe extern "C" fn destruct(ptr: *mut u8) {
drop(Arc::from_raw(ptr as *const ()));
}
static KEY: StaticKey = StaticKey::new(Some(destruct));
let shared1 = Arc::new(());
let shared2 = Arc::clone(&shared1);
unsafe {
assert!(KEY.get().is_null());
KEY.set(Arc::into_raw(shared1) as *mut u8);
}
thread::spawn(move || unsafe {
assert!(KEY.get().is_null());
KEY.set(Arc::into_raw(shared2) as *mut u8);
})
.join()
.unwrap();
// Leak the Arc, let the TLS destructor clean it up.
let shared1 = unsafe { ManuallyDrop::new(Arc::from_raw(KEY.get() as *const ())) };
assert_eq!(
Arc::strong_count(&shared1),
1,
"destructor should have dropped the other reference on thread exit"
);
}