kimchi_stubs/caml/
shared_rwlock.rs

1//! `impl_shared_rwlock` implements an OCaml custom type that wraps around a
2//! shared reference to RwLock to a Rust object.
3
4#[allow(unused_macros)]
5macro_rules! impl_shared_rwlock {
6    ($name: ident => $typ: ty) => {
7        #[derive(Debug, ::ocaml_gen::CustomType)]
8        pub struct $name(pub ::std::sync::Arc<::std::sync::RwLock<$typ>>);
9
10        //
11        // necessary ocaml.rs stuff
12        //
13
14        impl $name {
15            extern "C" fn caml_pointer_finalize(v: ::ocaml::Raw) {
16                unsafe {
17                    let v: ::ocaml::Pointer<Self> = v.as_pointer();
18                    v.drop_in_place();
19                }
20            }
21
22            extern "C" fn caml_pointer_compare(_: ::ocaml::Raw, _: ::ocaml::Raw) -> i32 {
23                // Always return equal. We can use this for sanity checks,
24                // anything else using this would be broken anyway.
25                0
26            }
27
28            pub fn new(x: $typ) -> Self {
29                Self(::std::sync::Arc::new(::std::sync::RwLock::new(x)))
30            }
31        }
32
33        ::ocaml::custom!($name {
34            finalize: $name::caml_pointer_finalize,
35            compare: $name::caml_pointer_compare,
36        });
37
38        unsafe impl<'a> ::ocaml::FromValue<'a> for $name {
39            fn from_value(value: ::ocaml::Value) -> Self {
40                let x: ::ocaml::Pointer<Self> = ::ocaml::FromValue::from_value(value);
41                Self(x.as_ref().0.clone())
42            }
43        }
44
45        //
46        // useful implementations
47        //
48
49        impl ::core::ops::Deref for $name {
50            type Target = ::std::sync::Arc<::std::sync::RwLock<$typ>>;
51
52            fn deref(&self) -> &Self::Target {
53                &self.0
54            }
55        }
56    };
57}