unsync.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. use crate::{
  2. error,
  3. references::{GenerationalRef, GenerationalRefMut},
  4. AnyStorage, GenerationalRefMutBorrowInfo, MemoryLocation, MemoryLocationInner, Storage,
  5. };
  6. use std::cell::{Ref, RefCell, RefMut};
  7. /// A unsync storage. This is the default storage type.
  8. pub struct UnsyncStorage(RefCell<Option<Box<dyn std::any::Any>>>);
  9. impl Default for UnsyncStorage {
  10. fn default() -> Self {
  11. Self(RefCell::new(None))
  12. }
  13. }
  14. impl<T: 'static> Storage<T> for UnsyncStorage {
  15. type Ref<R: ?Sized + 'static> = GenerationalRef<Ref<'static, R>>;
  16. type Mut<W: ?Sized + 'static> = GenerationalRefMut<RefMut<'static, W>>;
  17. fn try_read(
  18. &'static self,
  19. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  20. created_at: &'static std::panic::Location<'static>,
  21. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  22. at: crate::GenerationalRefBorrowInfo,
  23. ) -> Result<Self::Ref<T>, error::BorrowError> {
  24. let borrow = self.0.try_borrow();
  25. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  26. let borrow = borrow.map_err(|_| at.borrowed_from.borrow_error())?;
  27. #[cfg(not(any(debug_assertions, feature = "debug_ownership")))]
  28. let borrow = borrow.map_err(|_| {
  29. error::BorrowError::AlreadyBorrowedMut(error::AlreadyBorrowedMutError {})
  30. })?;
  31. Ref::filter_map(borrow, |any| any.as_ref()?.downcast_ref())
  32. .map_err(|_| {
  33. error::BorrowError::Dropped(error::ValueDroppedError {
  34. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  35. created_at,
  36. })
  37. })
  38. .map(|guard| {
  39. GenerationalRef::new(
  40. guard,
  41. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  42. at,
  43. )
  44. })
  45. }
  46. fn try_write(
  47. &'static self,
  48. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  49. created_at: &'static std::panic::Location<'static>,
  50. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  51. at: crate::GenerationalRefMutBorrowInfo,
  52. ) -> Result<Self::Mut<T>, error::BorrowMutError> {
  53. let borrow = self.0.try_borrow_mut();
  54. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  55. let borrow = borrow.map_err(|_| at.borrowed_from.borrow_mut_error())?;
  56. #[cfg(not(any(debug_assertions, feature = "debug_ownership")))]
  57. let borrow = borrow
  58. .map_err(|_| error::BorrowMutError::AlreadyBorrowed(error::AlreadyBorrowedError {}))?;
  59. RefMut::filter_map(borrow, |any| any.as_mut()?.downcast_mut())
  60. .map_err(|_| {
  61. error::BorrowMutError::Dropped(error::ValueDroppedError {
  62. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  63. created_at,
  64. })
  65. })
  66. .map(|guard| {
  67. GenerationalRefMut::new(
  68. guard,
  69. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  70. at,
  71. )
  72. })
  73. }
  74. fn set(&self, value: T) {
  75. *self.0.borrow_mut() = Some(Box::new(value));
  76. }
  77. fn try_map<I, U: ?Sized + 'static>(
  78. _self: Self::Ref<I>,
  79. f: impl FnOnce(&I) -> Option<&U>,
  80. ) -> Option<Self::Ref<U>> {
  81. let GenerationalRef {
  82. inner,
  83. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  84. borrow,
  85. ..
  86. } = _self;
  87. Ref::filter_map(inner, f).ok().map(|inner| GenerationalRef {
  88. inner,
  89. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  90. borrow,
  91. })
  92. }
  93. fn try_map_mut<I, U: ?Sized + 'static>(
  94. mut_ref: Self::Mut<I>,
  95. f: impl FnOnce(&mut I) -> Option<&mut U>,
  96. ) -> Option<Self::Mut<U>> {
  97. let GenerationalRefMut {
  98. inner,
  99. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  100. borrow,
  101. ..
  102. } = mut_ref;
  103. RefMut::filter_map(inner, f)
  104. .ok()
  105. .map(|inner| GenerationalRefMut {
  106. inner,
  107. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  108. borrow: GenerationalRefMutBorrowInfo {
  109. borrowed_from: borrow.borrowed_from,
  110. },
  111. })
  112. }
  113. }
  114. thread_local! {
  115. static UNSYNC_RUNTIME: RefCell<Vec<MemoryLocation<UnsyncStorage>>> = RefCell::new(Vec::new());
  116. }
  117. impl AnyStorage for UnsyncStorage {
  118. fn data_ptr(&self) -> *const () {
  119. self.0.as_ptr() as *const ()
  120. }
  121. fn take(&self) -> bool {
  122. self.0.borrow_mut().take().is_some()
  123. }
  124. fn claim() -> MemoryLocation<Self> {
  125. UNSYNC_RUNTIME.with(|runtime| {
  126. if let Some(location) = runtime.borrow_mut().pop() {
  127. location
  128. } else {
  129. let data: &'static MemoryLocationInner =
  130. &*Box::leak(Box::new(MemoryLocationInner {
  131. data: Self::default(),
  132. #[cfg(any(debug_assertions, feature = "check_generation"))]
  133. generation: 0.into(),
  134. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  135. borrow: Default::default(),
  136. }));
  137. MemoryLocation(data)
  138. }
  139. })
  140. }
  141. fn recycle(location: &MemoryLocation<Self>) {
  142. location.drop();
  143. UNSYNC_RUNTIME.with(|runtime| runtime.borrow_mut().push(*location));
  144. }
  145. }