| 1 | pub(crate) use self::inner::*; |
| 2 | |
| 3 | #[cfg (all(loom, any(test, feature = "loom" )))] |
| 4 | mod inner { |
| 5 | pub(crate) mod atomic { |
| 6 | pub use loom::sync::atomic::*; |
| 7 | pub use std::sync::atomic::Ordering; |
| 8 | } |
| 9 | pub(crate) use loom::{ |
| 10 | cell::UnsafeCell, hint, lazy_static, sync::Mutex, thread::yield_now, thread_local, |
| 11 | }; |
| 12 | |
| 13 | pub(crate) mod alloc { |
| 14 | #![allow (dead_code)] |
| 15 | use loom::alloc; |
| 16 | use std::fmt; |
| 17 | /// Track allocations, detecting leaks |
| 18 | /// |
| 19 | /// This is a version of `loom::alloc::Track` that adds a missing |
| 20 | /// `Default` impl. |
| 21 | pub struct Track<T>(alloc::Track<T>); |
| 22 | |
| 23 | impl<T> Track<T> { |
| 24 | /// Track a value for leaks |
| 25 | #[inline (always)] |
| 26 | pub fn new(value: T) -> Track<T> { |
| 27 | Track(alloc::Track::new(value)) |
| 28 | } |
| 29 | |
| 30 | /// Get a reference to the value |
| 31 | #[inline (always)] |
| 32 | pub fn get_ref(&self) -> &T { |
| 33 | self.0.get_ref() |
| 34 | } |
| 35 | |
| 36 | /// Get a mutable reference to the value |
| 37 | #[inline (always)] |
| 38 | pub fn get_mut(&mut self) -> &mut T { |
| 39 | self.0.get_mut() |
| 40 | } |
| 41 | |
| 42 | /// Stop tracking the value for leaks |
| 43 | #[inline (always)] |
| 44 | pub fn into_inner(self) -> T { |
| 45 | self.0.into_inner() |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | impl<T: fmt::Debug> fmt::Debug for Track<T> { |
| 50 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 51 | self.0.fmt(f) |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | impl<T: Default> Default for Track<T> { |
| 56 | fn default() -> Self { |
| 57 | Self::new(T::default()) |
| 58 | } |
| 59 | } |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | #[cfg (not(all(loom, any(feature = "loom" , test))))] |
| 64 | mod inner { |
| 65 | #![allow (dead_code)] |
| 66 | pub(crate) use lazy_static::lazy_static; |
| 67 | pub(crate) use std::{ |
| 68 | sync::{atomic, Mutex}, |
| 69 | thread::yield_now, |
| 70 | thread_local, |
| 71 | }; |
| 72 | |
| 73 | pub(crate) mod hint { |
| 74 | #[inline (always)] |
| 75 | pub(crate) fn spin_loop() { |
| 76 | // MSRV: std::hint::spin_loop() stabilized in 1.49.0 |
| 77 | #[allow (deprecated)] |
| 78 | super::atomic::spin_loop_hint() |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | #[derive (Debug)] |
| 83 | pub(crate) struct UnsafeCell<T>(std::cell::UnsafeCell<T>); |
| 84 | |
| 85 | impl<T> UnsafeCell<T> { |
| 86 | pub fn new(data: T) -> UnsafeCell<T> { |
| 87 | UnsafeCell(std::cell::UnsafeCell::new(data)) |
| 88 | } |
| 89 | |
| 90 | #[inline (always)] |
| 91 | pub fn with<F, R>(&self, f: F) -> R |
| 92 | where |
| 93 | F: FnOnce(*const T) -> R, |
| 94 | { |
| 95 | f(self.0.get()) |
| 96 | } |
| 97 | |
| 98 | #[inline (always)] |
| 99 | pub fn with_mut<F, R>(&self, f: F) -> R |
| 100 | where |
| 101 | F: FnOnce(*mut T) -> R, |
| 102 | { |
| 103 | f(self.0.get()) |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | pub(crate) mod alloc { |
| 108 | /// Track allocations, detecting leaks |
| 109 | #[derive (Debug, Default)] |
| 110 | pub struct Track<T> { |
| 111 | value: T, |
| 112 | } |
| 113 | |
| 114 | impl<T> Track<T> { |
| 115 | /// Track a value for leaks |
| 116 | #[inline (always)] |
| 117 | pub fn new(value: T) -> Track<T> { |
| 118 | Track { value } |
| 119 | } |
| 120 | |
| 121 | /// Get a reference to the value |
| 122 | #[inline (always)] |
| 123 | pub fn get_ref(&self) -> &T { |
| 124 | &self.value |
| 125 | } |
| 126 | |
| 127 | /// Get a mutable reference to the value |
| 128 | #[inline (always)] |
| 129 | pub fn get_mut(&mut self) -> &mut T { |
| 130 | &mut self.value |
| 131 | } |
| 132 | |
| 133 | /// Stop tracking the value for leaks |
| 134 | #[inline (always)] |
| 135 | pub fn into_inner(self) -> T { |
| 136 | self.value |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | } |
| 141 | |