[−][src]Trait pui::Identifier
An Identifier
is a process unique identifier
you are guaranteed that two instances of this identifier will never compare equal You can also get a cheap handle to the identifier, which you can use to mark other types as logically owned by the identifier.
For example, this pattern is sound
use pui::Identifier; use std::cell::UnsafeCell; struct Owner<I> { ident: I, } struct Handle<H, T: ?Sized> { handle: H, value: UnsafeCell<T>, } impl<H, T> Handle<H, T> { pub fn new(handle: H, value: T) -> Self { Self { handle, value: UnsafeCell::new(value) } } } impl<I> Owner<I> { pub fn new(ident: I) -> Self { Self { ident } } } impl<I: Identifier> Owner<I> { pub fn read<'a, T: ?Sized>(&'a self, handle: &'a Handle<I::Handle, T>) -> &'a T { assert!(self.ident.owns(&handle.handle)); // This is safe because `ident` owns the `handle`, which means that `self` // is the only `Owner` that could shared access the underlying value // This is because: // * the `Owner` owns the `Identifier` // * when we read/write, we bind the lifetime of `self` and `Handle` // to the lifetime of the output reference // * we have shared access to `*self` unsafe { &*handle.value.get() } } pub fn write<'a, T: ?Sized>(&'a mut self, handle: &'a Handle<I::Handle, T>) -> &'a mut T { assert!(self.ident.owns(&handle.handle)); // This is safe because `ident` owns the `handle`, which means that `self` // is the only `Owner` that could exclusive access the underlying value // This is because: // * the `Owner` owns the `Identifier` // * when we read/write, we bind the lifetime of `self` and `Handle` // to the lifetime of the output reference // * we have exclusive access to `*self` unsafe { &mut *handle.value.get() } } }
Safety
ident.owns(&handle)
must return true for anyhandle
returned fromident.handle()
regardless of when the handle was created.- If two handles compare equal, then
Identifier::owns
must act the same for both of them- i.e. it must return false for both handles, or it must return true for both handles
- Two instances of
Identifier
must never return true for the same handle if they can both exist on the same thread. - In particular, it is unsound to implement
Identifier
on references
Associated Types
Loading content...Required methods
pub fn handle(&self) -> Self::Handle
[src]
Create a handle that this identifier owns
pub fn owns(&self, handle: &Self::Handle) -> bool
[src]
Check the current identifier owns the given handle
Implementations on Foreign Types
impl<I: Identifier + ?Sized> Identifier for Box<I>
[src]
type Handle = I::Handle
pub fn handle(&self) -> Self::Handle
[src]
pub fn owns(&self, handle: &Self::Handle) -> bool
[src]
Implementors
impl<'id> Identifier for Scoped<'id>
[src]
type Handle = ScopedHandle<'id>
pub fn handle(&self) -> ScopedHandle<'id>
[src]
pub fn owns(&self, _: &Self::Handle) -> bool
[src]
impl<I: IdAlloc, P: PoolMut<I::Id>> Identifier for Runtime<I, P>
[src]
type Handle = RuntimeHandle<I>
pub fn handle(&self) -> Self::Handle
[src]
pub fn owns(&self, handle: &Self::Handle) -> bool
[src]
impl<T> Identifier for pui::typeid::Type<T>
[src]
type Handle = TypeHandle<T>
pub fn handle(&self) -> TypeHandle<T>
[src]
pub fn owns(&self, _: &Self::Handle) -> bool
[src]
impl<T> Identifier for pui::typeid_tl::Type<T>
[src]
This is supported on crate feature
std
only.