/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::{fmt, sync::Arc};
/// Object handle /// /// Handles opaque `u64` values used to pass objects across the FFI, both for objects implemented in /// Rust and ones implemented in the foreign language. /// /// Rust handles are generated by leaking a raw pointer /// Foreign handles are generated with a handle map that only generates odd values. /// For all currently supported architectures and hopefully any ones we add in the future: /// * 0 is an invalid value. /// * The lowest bit will always be set for foreign handles and never set for Rust ones (since the /// leaked pointer will be aligned to `size_of::<Arc<T>>()` == `size_of::<*const T>()`). /// /// Rust handles are mainly managed is through the [crate::HandleAlloc] trait. #[derive(Clone, Default, PartialEq, Eq)] #[repr(transparent)] pubstruct Handle(u64);
pubfn as_pointer<T>(&self) -> *const T { self.0as *const T
}
/// Was this handle generated by the foreign side of the FFI? pubfn is_foreign(&self) -> bool { // Foreign handles have the lowest bit set. // We know that Rust handles will never have this set, since the pointers that they're cast from have alignment > 1; // https://mozilla.github.io/uniffi-rs/latest/internals/object_references.html
(self.0 & 1) == 1
}
/// # Safety /// The raw value must be a valid handle as described above. pubunsafefn from_raw(raw: u64) -> Option<Self> { if raw == 0 {
None
} else {
Some(Self(raw))
}
}
/// Create a handle from an Arc pubfn from_arc<T>(arc: Arc<T>) -> Self { Self::from_pointer(Arc::into_raw(arc))
}
/// Re-create an Arc from a handle /// /// # Safety /// /// * The handle must have been created from `Handle::from_arc`. /// * The handle must only be used once pubunsafefn into_arc<T>(self) -> Arc<T> {
Arc::from_raw(self.as_pointer())
}
/// Re-create an Arc from a borrowed handle /// /// "borrowed" means a handle sent from the other side of the FFI without cloning it first. /// Be very careful with using this, since it's easy to introduce races. /// The one scenario this is currently used for is futures, since we can guarantee that the /// foreign side will not drop the future while in the middle of polling/cancelling it. /// /// # Safety /// /// * The handle must have been created from `Handle::from_arc`. /// * There must be no possibility for the handle to be dropped before the function the /// borrowed handle is passed to returns. pubunsafefn into_arc_borrowed<T>(self) -> Arc<T> { self.clone_arc_handle::<T>();
Arc::from_raw(self.as_pointer())
}
/// Clone a handle for an Arc /// /// # Safety /// /// The handle must have been created from `Handle::from_arc`. pubunsafefn clone_arc_handle<T>(&self) -> Self {
Arc::increment_strong_count(self.as_pointer::<T>()); // This is safe because we just incremented the refcount. Self(self.0)
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.