fbl/
opaque_ref_counted.rs1use crate::ref_counted::{HasRefCount, RefCounted};
8use zr::Opaque;
9
10#[repr(transparent)]
13pub struct OpaqueRefCounted<T>(Opaque<T>);
14
15impl<T> OpaqueRefCounted<T> {
16 pub fn get(&self) -> *mut T {
18 self.0.get()
19 }
20}
21
22impl<T> HasRefCount for OpaqueRefCounted<T> {
23 fn ref_count(&self) -> &RefCounted {
24 unsafe { &*(self.get() as *const RefCounted) }
26 }
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32 use crate::recyclable::Recyclable;
33 use crate::ref_ptr::RefPtr;
34 use core::ffi::c_void;
35 use core::ptr::NonNull;
36
37 unsafe extern "C" {
38 fn create_cpp_ref_counted_object(destroyed: *mut bool) -> *mut c_void;
39 fn destroy_cpp_ref_counted_object(ptr: *mut c_void);
40 }
41
42 pub struct TestCppRefCountedObject;
43
44 unsafe impl Recyclable for OpaqueRefCounted<TestCppRefCountedObject> {
45 unsafe fn recycle(ptr: NonNull<Self>) {
46 unsafe {
47 destroy_cpp_ref_counted_object(ptr.as_ptr() as *mut c_void);
48 }
49 }
50
51 fn allocate(_value: Self) -> Result<NonNull<Self>, ::kalloc::AllocError> {
52 Err(::kalloc::AllocError)
53 }
54 }
55
56 #[test]
57 #[cfg_attr(miri, ignore = "miri does not support calling foreign functions")]
58 fn test_cross_lang_ref_ptr() {
59 use core::sync::atomic::{AtomicBool, Ordering};
60
61 let destroyed = AtomicBool::new(false);
62 unsafe {
63 let raw_ptr = create_cpp_ref_counted_object(destroyed.as_ptr());
64 assert!(!destroyed.load(Ordering::Relaxed));
65
66 {
67 let ref_ptr =
68 RefPtr::from_raw(raw_ptr as *mut OpaqueRefCounted<TestCppRefCountedObject>);
69 assert!(!destroyed.load(Ordering::Relaxed));
70
71 let ref_ptr_clone = ref_ptr.clone();
72 assert!(!destroyed.load(Ordering::Relaxed));
73
74 drop(ref_ptr_clone);
76 assert!(!destroyed.load(Ordering::Relaxed));
77 } assert!(destroyed.load(Ordering::Relaxed));
80 }
81 }
82
83 #[test]
84 fn test_opaque_ref_counted_allocate_fails() {
85 let val = OpaqueRefCounted(Opaque::uninit());
86 let res = OpaqueRefCounted::<TestCppRefCountedObject>::allocate(val);
87 assert!(res.is_err());
88 }
89}