Path: blob/main/crates/bevy_platform/src/cell/sync_cell.rs
6849 views
#![expect(unsafe_code, reason = "SyncCell requires unsafe code.")]12//! A reimplementation of the currently unstable [`std::sync::Exclusive`]3//!4//! [`std::sync::Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html56use core::ptr;78/// See [`Exclusive`](https://github.com/rust-lang/rust/issues/98407) for stdlib's upcoming implementation,9/// which should replace this one entirely.10///11/// Provides a wrapper that allows making any type unconditionally [`Sync`] by only providing mutable access.12#[repr(transparent)]13pub struct SyncCell<T: ?Sized> {14inner: T,15}1617impl<T: Sized> SyncCell<T> {18/// Construct a new instance of a `SyncCell` from the given value.19pub fn new(inner: T) -> Self {20Self { inner }21}2223/// Deconstruct this `SyncCell` into its inner value.24pub fn to_inner(Self { inner }: Self) -> T {25inner26}27}2829impl<T: ?Sized> SyncCell<T> {30/// Get a reference to this `SyncCell`'s inner value.31pub fn get(&mut self) -> &mut T {32&mut self.inner33}3435/// For types that implement [`Sync`], get shared access to this `SyncCell`'s inner value.36pub fn read(&self) -> &T37where38T: Sync,39{40&self.inner41}4243/// Build a mutable reference to a `SyncCell` from a mutable reference44/// to its inner value, to skip constructing with [`new()`](SyncCell::new()).45pub fn from_mut(r: &'_ mut T) -> &'_ mut SyncCell<T> {46// SAFETY: repr is transparent, so refs have the same layout; and `SyncCell` properties are `&mut`-agnostic47unsafe { &mut *(ptr::from_mut(r) as *mut SyncCell<T>) }48}49}5051// SAFETY: `Sync` only allows multithreaded access via immutable reference.52// As `SyncCell` requires an exclusive reference to access the wrapped value for `!Sync` types,53// marking this type as `Sync` does not actually allow unsynchronized access to the inner value.54unsafe impl<T: ?Sized> Sync for SyncCell<T> {}555657