lib.rs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #![cfg_attr(feature = "no_std", no_std)]
  2. #[cfg(feature = "no_std")]
  3. use core::{
  4. cell::UnsafeCell,
  5. marker::PhantomData,
  6. ops::{Deref, DerefMut},
  7. sync::atomic::{AtomicBool, Ordering},
  8. };
  9. #[cfg(not(feature = "no_std"))]
  10. use std::{
  11. cell::UnsafeCell,
  12. marker::PhantomData,
  13. ops::{Deref, DerefMut},
  14. sync::atomic::{AtomicBool, Ordering},
  15. };
  16. #[cfg(test)]
  17. mod tests {
  18. use super::*;
  19. #[test]
  20. fn test() {
  21. let cell = AtomicUniqueRefCell::new(42);
  22. let mut ref_cell = cell.borrow();
  23. assert_eq!(*ref_cell, 42);
  24. *ref_cell = 43;
  25. assert_eq!(*ref_cell, 43);
  26. }
  27. }
  28. /// `AtomicUniqueRefCell` implements `Send` and `Sync` if `T` is `Send`.
  29. /// The following code will not compile if `T` is not `Send`.
  30. ///
  31. /// ```compile_fail
  32. /// use atomic_unique_refcell::AtomicUniqueRefCell;
  33. ///
  34. /// struct NotSend {
  35. /// data: *mut (),
  36. /// }
  37. ///
  38. /// struct Test {
  39. /// data: AtomicUniqueRefCell<NotSend>,
  40. /// }
  41. ///
  42. /// trait TestTrait: Send + Sync {}
  43. ///
  44. /// impl TestTrait for Test {}
  45. /// ```
  46. pub struct AtomicUniqueRefCell<T: ?Sized> {
  47. count: AtomicBool,
  48. inner: UnsafeCell<T>,
  49. }
  50. unsafe impl<T: ?Sized + Send> Send for AtomicUniqueRefCell<T> {}
  51. unsafe impl<T: ?Sized + Send> Sync for AtomicUniqueRefCell<T> {}
  52. pub struct Ref<'a, T: ?Sized> {
  53. inner: &'a AtomicUniqueRefCell<T>,
  54. _marker: PhantomData<UnsafeCell<T>>,
  55. }
  56. impl<T> AtomicUniqueRefCell<T> {
  57. pub fn new(value: T) -> Self {
  58. Self {
  59. count: AtomicBool::new(false),
  60. inner: UnsafeCell::new(value),
  61. }
  62. }
  63. }
  64. impl<T: ?Sized> AtomicUniqueRefCell<T> {
  65. pub fn borrow(&self) -> Ref<'_, T> {
  66. if self.count.swap(true, Ordering::Acquire) {
  67. panic!("Already borrowed");
  68. }
  69. Ref {
  70. inner: self,
  71. _marker: PhantomData,
  72. }
  73. }
  74. }
  75. impl<T: ?Sized> Deref for Ref<'_, T> {
  76. type Target = T;
  77. fn deref(&self) -> &Self::Target {
  78. unsafe { &*self.inner.inner.get() }
  79. }
  80. }
  81. impl<T: ?Sized> DerefMut for Ref<'_, T> {
  82. fn deref_mut(&mut self) -> &mut Self::Target {
  83. unsafe { &mut *self.inner.inner.get() }
  84. }
  85. }
  86. impl<T: ?Sized> Drop for Ref<'_, T> {
  87. fn drop(&mut self) {
  88. self.inner.count.swap(false, Ordering::Release);
  89. }
  90. }