arc_field.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2024 Google LLC.
  3. //! A field that is exclusively owned by a [`ListArc`].
  4. //!
  5. //! This can be used to have reference counted struct where one of the reference counted pointers
  6. //! has exclusive access to a field of the struct.
  7. //!
  8. //! [`ListArc`]: crate::list::ListArc
  9. use core::cell::UnsafeCell;
  10. /// A field owned by a specific [`ListArc`].
  11. ///
  12. /// [`ListArc`]: crate::list::ListArc
  13. pub struct ListArcField<T, const ID: u64 = 0> {
  14. value: UnsafeCell<T>,
  15. }
  16. // SAFETY: If the inner type is thread-safe, then it's also okay for `ListArc` to be thread-safe.
  17. unsafe impl<T: Send + Sync, const ID: u64> Send for ListArcField<T, ID> {}
  18. // SAFETY: If the inner type is thread-safe, then it's also okay for `ListArc` to be thread-safe.
  19. unsafe impl<T: Send + Sync, const ID: u64> Sync for ListArcField<T, ID> {}
  20. impl<T, const ID: u64> ListArcField<T, ID> {
  21. /// Creates a new `ListArcField`.
  22. pub fn new(value: T) -> Self {
  23. Self {
  24. value: UnsafeCell::new(value),
  25. }
  26. }
  27. /// Access the value when we have exclusive access to the `ListArcField`.
  28. ///
  29. /// This allows access to the field using an `UniqueArc` instead of a `ListArc`.
  30. pub fn get_mut(&mut self) -> &mut T {
  31. self.value.get_mut()
  32. }
  33. /// Unsafely assert that you have shared access to the `ListArc` for this field.
  34. ///
  35. /// # Safety
  36. ///
  37. /// The caller must have shared access to the `ListArc<ID>` containing the struct with this
  38. /// field for the duration of the returned reference.
  39. pub unsafe fn assert_ref(&self) -> &T {
  40. // SAFETY: The caller has shared access to the `ListArc`, so they also have shared access
  41. // to this field.
  42. unsafe { &*self.value.get() }
  43. }
  44. /// Unsafely assert that you have mutable access to the `ListArc` for this field.
  45. ///
  46. /// # Safety
  47. ///
  48. /// The caller must have mutable access to the `ListArc<ID>` containing the struct with this
  49. /// field for the duration of the returned reference.
  50. #[expect(clippy::mut_from_ref)]
  51. pub unsafe fn assert_mut(&self) -> &mut T {
  52. // SAFETY: The caller has exclusive access to the `ListArc`, so they also have exclusive
  53. // access to this field.
  54. unsafe { &mut *self.value.get() }
  55. }
  56. }
  57. /// Defines getters for a [`ListArcField`].
  58. #[macro_export]
  59. macro_rules! define_list_arc_field_getter {
  60. ($pub:vis fn $name:ident(&self $(<$id:tt>)?) -> &$typ:ty { $field:ident }
  61. $($rest:tt)*
  62. ) => {
  63. $pub fn $name<'a>(self: &'a $crate::list::ListArc<Self $(, $id)?>) -> &'a $typ {
  64. let field = &(&**self).$field;
  65. // SAFETY: We have a shared reference to the `ListArc`.
  66. unsafe { $crate::list::ListArcField::<$typ $(, $id)?>::assert_ref(field) }
  67. }
  68. $crate::list::define_list_arc_field_getter!($($rest)*);
  69. };
  70. ($pub:vis fn $name:ident(&mut self $(<$id:tt>)?) -> &mut $typ:ty { $field:ident }
  71. $($rest:tt)*
  72. ) => {
  73. $pub fn $name<'a>(self: &'a mut $crate::list::ListArc<Self $(, $id)?>) -> &'a mut $typ {
  74. let field = &(&**self).$field;
  75. // SAFETY: We have a mutable reference to the `ListArc`.
  76. unsafe { $crate::list::ListArcField::<$typ $(, $id)?>::assert_mut(field) }
  77. }
  78. $crate::list::define_list_arc_field_getter!($($rest)*);
  79. };
  80. () => {};
  81. }
  82. pub use define_list_arc_field_getter;