Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_platform/src/cell/sync_cell.rs
6849 views
1
#![expect(unsafe_code, reason = "SyncCell requires unsafe code.")]
2
3
//! A reimplementation of the currently unstable [`std::sync::Exclusive`]
4
//!
5
//! [`std::sync::Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
6
7
use core::ptr;
8
9
/// See [`Exclusive`](https://github.com/rust-lang/rust/issues/98407) for stdlib's upcoming implementation,
10
/// which should replace this one entirely.
11
///
12
/// Provides a wrapper that allows making any type unconditionally [`Sync`] by only providing mutable access.
13
#[repr(transparent)]
14
pub struct SyncCell<T: ?Sized> {
15
inner: T,
16
}
17
18
impl<T: Sized> SyncCell<T> {
19
/// Construct a new instance of a `SyncCell` from the given value.
20
pub fn new(inner: T) -> Self {
21
Self { inner }
22
}
23
24
/// Deconstruct this `SyncCell` into its inner value.
25
pub fn to_inner(Self { inner }: Self) -> T {
26
inner
27
}
28
}
29
30
impl<T: ?Sized> SyncCell<T> {
31
/// Get a reference to this `SyncCell`'s inner value.
32
pub fn get(&mut self) -> &mut T {
33
&mut self.inner
34
}
35
36
/// For types that implement [`Sync`], get shared access to this `SyncCell`'s inner value.
37
pub fn read(&self) -> &T
38
where
39
T: Sync,
40
{
41
&self.inner
42
}
43
44
/// Build a mutable reference to a `SyncCell` from a mutable reference
45
/// to its inner value, to skip constructing with [`new()`](SyncCell::new()).
46
pub fn from_mut(r: &'_ mut T) -> &'_ mut SyncCell<T> {
47
// SAFETY: repr is transparent, so refs have the same layout; and `SyncCell` properties are `&mut`-agnostic
48
unsafe { &mut *(ptr::from_mut(r) as *mut SyncCell<T>) }
49
}
50
}
51
52
// SAFETY: `Sync` only allows multithreaded access via immutable reference.
53
// As `SyncCell` requires an exclusive reference to access the wrapped value for `!Sync` types,
54
// marking this type as `Sync` does not actually allow unsynchronized access to the inner value.
55
unsafe impl<T: ?Sized> Sync for SyncCell<T> {}
56
57