sync.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. use parking_lot::{
  2. MappedRwLockReadGuard, MappedRwLockWriteGuard, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard,
  3. };
  4. use std::sync::{Arc, OnceLock};
  5. use crate::{
  6. error::{self, ValueDroppedError},
  7. references::{GenerationalRef, GenerationalRefMut},
  8. AnyStorage, MemoryLocation, MemoryLocationInner, Storage,
  9. };
  10. /// A thread safe storage. This is slower than the unsync storage, but allows you to share the value between threads.
  11. #[derive(Default)]
  12. pub struct SyncStorage(RwLock<Option<Box<dyn std::any::Any + Send + Sync>>>);
  13. static SYNC_RUNTIME: OnceLock<Arc<Mutex<Vec<MemoryLocation<SyncStorage>>>>> = OnceLock::new();
  14. fn sync_runtime() -> &'static Arc<Mutex<Vec<MemoryLocation<SyncStorage>>>> {
  15. SYNC_RUNTIME.get_or_init(|| Arc::new(Mutex::new(Vec::new())))
  16. }
  17. impl AnyStorage for SyncStorage {
  18. type Ref<'a, R: ?Sized + 'static> = GenerationalRef<MappedRwLockReadGuard<'a, R>>;
  19. type Mut<'a, W: ?Sized + 'static> = GenerationalRefMut<MappedRwLockWriteGuard<'a, W>>;
  20. fn downcast_lifetime_ref<'a: 'b, 'b, T: ?Sized + 'static>(
  21. ref_: Self::Ref<'a, T>,
  22. ) -> Self::Ref<'b, T> {
  23. ref_
  24. }
  25. fn downcast_lifetime_mut<'a: 'b, 'b, T: ?Sized + 'static>(
  26. mut_: Self::Mut<'a, T>,
  27. ) -> Self::Mut<'b, T> {
  28. mut_
  29. }
  30. fn try_map<I: ?Sized + 'static, U: ?Sized + 'static>(
  31. ref_: Self::Ref<'_, I>,
  32. f: impl FnOnce(&I) -> Option<&U>,
  33. ) -> Option<Self::Ref<'_, U>> {
  34. let GenerationalRef {
  35. inner,
  36. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  37. borrow,
  38. ..
  39. } = ref_;
  40. MappedRwLockReadGuard::try_map(inner, f)
  41. .ok()
  42. .map(|inner| GenerationalRef {
  43. inner,
  44. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  45. borrow: crate::GenerationalRefBorrowInfo {
  46. borrowed_at: borrow.borrowed_at,
  47. borrowed_from: borrow.borrowed_from,
  48. created_at: borrow.created_at,
  49. },
  50. })
  51. }
  52. fn try_map_mut<I: ?Sized + 'static, U: ?Sized + 'static>(
  53. mut_ref: Self::Mut<'_, I>,
  54. f: impl FnOnce(&mut I) -> Option<&mut U>,
  55. ) -> Option<Self::Mut<'_, U>> {
  56. let GenerationalRefMut {
  57. inner,
  58. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  59. borrow,
  60. ..
  61. } = mut_ref;
  62. MappedRwLockWriteGuard::try_map(inner, f)
  63. .ok()
  64. .map(|inner| GenerationalRefMut {
  65. inner,
  66. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  67. borrow: crate::GenerationalRefMutBorrowInfo {
  68. borrowed_from: borrow.borrowed_from,
  69. created_at: borrow.created_at,
  70. },
  71. })
  72. }
  73. fn data_ptr(&self) -> *const () {
  74. self.0.data_ptr() as *const ()
  75. }
  76. fn manually_drop(&self) -> bool {
  77. self.0.write().take().is_some()
  78. }
  79. fn claim() -> MemoryLocation<Self> {
  80. sync_runtime().lock().pop().unwrap_or_else(|| {
  81. let data: &'static MemoryLocationInner<Self> =
  82. &*Box::leak(Box::new(MemoryLocationInner {
  83. data: Self::default(),
  84. #[cfg(any(debug_assertions, feature = "check_generation"))]
  85. generation: 0.into(),
  86. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  87. borrow: Default::default(),
  88. }));
  89. MemoryLocation(data)
  90. })
  91. }
  92. fn recycle(location: &MemoryLocation<Self>) {
  93. location.drop();
  94. sync_runtime().lock().push(*location);
  95. }
  96. }
  97. impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
  98. fn try_read(
  99. &'static self,
  100. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  101. at: crate::GenerationalRefBorrowInfo,
  102. ) -> Result<Self::Ref<'static, T>, error::BorrowError> {
  103. let read = self.0.try_read();
  104. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  105. let read = read.ok_or_else(|| at.borrowed_from.borrow_error())?;
  106. #[cfg(not(any(debug_assertions, feature = "debug_ownership")))]
  107. let read = read.ok_or_else(|| {
  108. error::BorrowError::AlreadyBorrowedMut(error::AlreadyBorrowedMutError {})
  109. })?;
  110. RwLockReadGuard::try_map(read, |any| any.as_ref()?.downcast_ref())
  111. .map_err(|_| {
  112. error::BorrowError::Dropped(ValueDroppedError {
  113. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  114. created_at: at.created_at,
  115. })
  116. })
  117. .map(|guard| {
  118. GenerationalRef::new(
  119. guard,
  120. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  121. at,
  122. )
  123. })
  124. }
  125. fn try_write(
  126. &'static self,
  127. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  128. at: crate::GenerationalRefMutBorrowInfo,
  129. ) -> Result<Self::Mut<'static, T>, error::BorrowMutError> {
  130. let write = self.0.write();
  131. RwLockWriteGuard::try_map(write, |any| any.as_mut()?.downcast_mut())
  132. .map_err(|_| {
  133. error::BorrowMutError::Dropped(ValueDroppedError {
  134. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  135. created_at: at.created_at,
  136. })
  137. })
  138. .map(|guard| {
  139. GenerationalRefMut::new(
  140. guard,
  141. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  142. at,
  143. )
  144. })
  145. }
  146. fn set(&self, value: T) {
  147. *self.0.write() = Some(Box::new(value));
  148. }
  149. fn take(&'static self) -> Option<T> {
  150. self.0
  151. .write()
  152. .take()
  153. .and_then(|any| any.downcast().ok().map(|boxed| *boxed))
  154. }
  155. }