| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- // SPDX-License-Identifier: GPL-2.0
- // Copyright (C) 2024 Google LLC.
- //! A field that is exclusively owned by a [`ListArc`].
- //!
- //! This can be used to have reference counted struct where one of the reference counted pointers
- //! has exclusive access to a field of the struct.
- //!
- //! [`ListArc`]: crate::list::ListArc
- use core::cell::UnsafeCell;
- /// A field owned by a specific [`ListArc`].
- ///
- /// [`ListArc`]: crate::list::ListArc
- pub struct ListArcField<T, const ID: u64 = 0> {
- value: UnsafeCell<T>,
- }
- // SAFETY: If the inner type is thread-safe, then it's also okay for `ListArc` to be thread-safe.
- unsafe impl<T: Send + Sync, const ID: u64> Send for ListArcField<T, ID> {}
- // SAFETY: If the inner type is thread-safe, then it's also okay for `ListArc` to be thread-safe.
- unsafe impl<T: Send + Sync, const ID: u64> Sync for ListArcField<T, ID> {}
- impl<T, const ID: u64> ListArcField<T, ID> {
- /// Creates a new `ListArcField`.
- pub fn new(value: T) -> Self {
- Self {
- value: UnsafeCell::new(value),
- }
- }
- /// Access the value when we have exclusive access to the `ListArcField`.
- ///
- /// This allows access to the field using an `UniqueArc` instead of a `ListArc`.
- pub fn get_mut(&mut self) -> &mut T {
- self.value.get_mut()
- }
- /// Unsafely assert that you have shared access to the `ListArc` for this field.
- ///
- /// # Safety
- ///
- /// The caller must have shared access to the `ListArc<ID>` containing the struct with this
- /// field for the duration of the returned reference.
- pub unsafe fn assert_ref(&self) -> &T {
- // SAFETY: The caller has shared access to the `ListArc`, so they also have shared access
- // to this field.
- unsafe { &*self.value.get() }
- }
- /// Unsafely assert that you have mutable access to the `ListArc` for this field.
- ///
- /// # Safety
- ///
- /// The caller must have mutable access to the `ListArc<ID>` containing the struct with this
- /// field for the duration of the returned reference.
- #[expect(clippy::mut_from_ref)]
- pub unsafe fn assert_mut(&self) -> &mut T {
- // SAFETY: The caller has exclusive access to the `ListArc`, so they also have exclusive
- // access to this field.
- unsafe { &mut *self.value.get() }
- }
- }
- /// Defines getters for a [`ListArcField`].
- #[macro_export]
- macro_rules! define_list_arc_field_getter {
- ($pub:vis fn $name:ident(&self $(<$id:tt>)?) -> &$typ:ty { $field:ident }
- $($rest:tt)*
- ) => {
- $pub fn $name<'a>(self: &'a $crate::list::ListArc<Self $(, $id)?>) -> &'a $typ {
- let field = &(&**self).$field;
- // SAFETY: We have a shared reference to the `ListArc`.
- unsafe { $crate::list::ListArcField::<$typ $(, $id)?>::assert_ref(field) }
- }
- $crate::list::define_list_arc_field_getter!($($rest)*);
- };
- ($pub:vis fn $name:ident(&mut self $(<$id:tt>)?) -> &mut $typ:ty { $field:ident }
- $($rest:tt)*
- ) => {
- $pub fn $name<'a>(self: &'a mut $crate::list::ListArc<Self $(, $id)?>) -> &'a mut $typ {
- let field = &(&**self).$field;
- // SAFETY: We have a mutable reference to the `ListArc`.
- unsafe { $crate::list::ListArcField::<$typ $(, $id)?>::assert_mut(field) }
- }
- $crate::list::define_list_arc_field_getter!($($rest)*);
- };
- () => {};
- }
- pub use define_list_arc_field_getter;
|