diff --git a/src/util.rs b/src/util.rs index d5109066..67539adf 100644 --- a/src/util.rs +++ b/src/util.rs @@ -16,6 +16,7 @@ pub mod c { use std::os::raw::c_char; use std::rc::Rc; use std::str::Utf8Error; + use std::sync::{ Arc, Mutex }; // traits @@ -129,6 +130,40 @@ pub mod c { } impl COpaquePtr for Wrapped {} + + #[repr(transparent)] + pub struct ArcWrapped(*const Mutex); + + impl ArcWrapped { + pub fn new(value: T) -> Self { + Self::wrap(Arc::new(Mutex::new(value))) + } + pub fn wrap(state: Arc>) -> Self { + Self(Arc::into_raw(state)) + } + + /// Extracts the reference to the data. + /// It may cause problems if attempted in more than one place + pub unsafe fn unwrap(self) -> Arc> { + Arc::from_raw(self.0) + } + + /// Creates a new reference to the same data. + /// Use for accessing the underlying data as a reference. + pub fn clone_ref(&self) -> Arc> { + // A bit dangerous: the Arc may be in use elsewhere + let used_rc = unsafe { Arc::from_raw(self.0) }; + let rc = used_rc.clone(); + Arc::into_raw(used_rc); // prevent dropping the original reference + rc + } + } + + impl Clone for ArcWrapped { + fn clone(&self) -> Self { + Self::wrap(self.clone_ref()) + } + } } /// Clones the underlying data structure, like ToOwned.