• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![doc(test(attr(deny(warnings))))]
2 #![warn(missing_docs)]
3 #![cfg_attr(docsrs, feature(doc_cfg))]
4 #![allow(deprecated)]
5 #![cfg_attr(feature = "experimental-thread-local", no_std)]
6 #![cfg_attr(feature = "experimental-thread-local", feature(thread_local))]
7 
8 //! Making [`Arc`][Arc] itself atomic
9 //!
10 //! The [`ArcSwap`] type is a container for an `Arc` that can be changed atomically. Semantically,
11 //! it is similar to something like `Atomic<Arc<T>>` (if there was such a thing) or
12 //! `RwLock<Arc<T>>` (but without the need for the locking). It is optimized for read-mostly
13 //! scenarios, with consistent performance characteristics.
14 //!
15 //! # Motivation
16 //!
17 //! There are many situations in which one might want to have some data structure that is often
18 //! read and seldom updated. Some examples might be a configuration of a service, routing tables,
19 //! snapshot of some data that is renewed every few minutes, etc.
20 //!
21 //! In all these cases one needs:
22 //! * Being able to read the current value of the data structure, fast, often and concurrently from
23 //!   many threads.
24 //! * Using the same version of the data structure over longer period of time ‒ a query should be
25 //!   answered by a consistent version of data, a packet should be routed either by an old or by a
26 //!   new version of the routing table but not by a combination, etc.
27 //! * Perform an update without disrupting the processing.
28 //!
29 //! The first idea would be to use [`RwLock<T>`][RwLock] and keep a read-lock for the whole time of
30 //! processing. Update would, however, pause all processing until done.
31 //!
32 //! Better option would be to have [`RwLock<Arc<T>>`][RwLock]. Then one would lock, clone the [Arc]
33 //! and unlock. This suffers from CPU-level contention (on the lock and on the reference count of
34 //! the [Arc]) which makes it relatively slow. Depending on the implementation, an update may be
35 //! blocked for arbitrary long time by a steady inflow of readers.
36 //!
37 //! ```rust
38 //! # use std::sync::{Arc, RwLock};
39 //! # use once_cell::sync::Lazy;
40 //! # struct RoutingTable; struct Packet; impl RoutingTable { fn route(&self, _: Packet) {} }
41 //! static ROUTING_TABLE: Lazy<RwLock<Arc<RoutingTable>>> = Lazy::new(|| {
42 //!     RwLock::new(Arc::new(RoutingTable))
43 //! });
44 //!
45 //! fn process_packet(packet: Packet) {
46 //!     let table = Arc::clone(&ROUTING_TABLE.read().unwrap());
47 //!     table.route(packet);
48 //! }
49 //! # fn main() { process_packet(Packet); }
50 //! ```
51 //!
52 //! The [ArcSwap] can be used instead, which solves the above problems and has better performance
53 //! characteristics than the [RwLock], both in contended and non-contended scenarios.
54 //!
55 //! ```rust
56 //! # use arc_swap::ArcSwap;
57 //! # use once_cell::sync::Lazy;
58 //! # struct RoutingTable; struct Packet; impl RoutingTable { fn route(&self, _: Packet) {} }
59 //! static ROUTING_TABLE: Lazy<ArcSwap<RoutingTable>> = Lazy::new(|| {
60 //!     ArcSwap::from_pointee(RoutingTable)
61 //! });
62 //!
63 //! fn process_packet(packet: Packet) {
64 //!     let table = ROUTING_TABLE.load();
65 //!     table.route(packet);
66 //! }
67 //! # fn main() { process_packet(Packet); }
68 //! ```
69 //!
70 //! # Crate contents
71 //!
72 //! At the heart of the crate there are [`ArcSwap`] and [`ArcSwapOption`] types, containers for an
73 //! [`Arc`] and [`Option<Arc>`][Option].
74 //!
75 //! Technically, these are type aliases for partial instantiations of the [`ArcSwapAny`] type. The
76 //! [`ArcSwapAny`] is more flexible and allows tweaking of many things (can store other things than
77 //! [`Arc`]s, can configure the locking [`Strategy`]). For details about the tweaking, see the
78 //! documentation of the [`strategy`] module and the [`RefCnt`] trait.
79 //!
80 //! The [`cache`] module provides means for speeding up read access of the contained data at the
81 //! cost of delayed reclamation.
82 //!
83 //! The [`access`] module can be used to do projections into the contained data to separate parts
84 //! of application from each other (eg. giving a component access to only its own part of
85 //! configuration while still having it reloaded as a whole).
86 //!
87 //! # Before using
88 //!
89 //! The data structure is a bit niche. Before using, please check the
90 //! [limitations and common pitfalls][docs::limitations] and the [performance
91 //! characteristics][docs::performance], including choosing the right [read
92 //! operation][docs::performance#read-operations].
93 //!
94 //! You can also get an inspiration about what's possible in the [common patterns][docs::patterns]
95 //! section.
96 //!
97 //! # Examples
98 //!
99 //! ```rust
100 //! use std::sync::Arc;
101 //!
102 //! use arc_swap::ArcSwap;
103 //! use crossbeam_utils::thread;
104 //!
105 //! let config = ArcSwap::from(Arc::new(String::default()));
106 //! thread::scope(|scope| {
107 //!     scope.spawn(|_| {
108 //!         let new_conf = Arc::new("New configuration".to_owned());
109 //!         config.store(new_conf);
110 //!     });
111 //!     for _ in 0..10 {
112 //!         scope.spawn(|_| {
113 //!             loop {
114 //!                 let cfg = config.load();
115 //!                 if !cfg.is_empty() {
116 //!                     assert_eq!(**cfg, "New configuration");
117 //!                     return;
118 //!                 }
119 //!             }
120 //!         });
121 //!     }
122 //! }).unwrap();
123 //! ```
124 //!
125 //! [RwLock]: https://doc.rust-lang.org/std/sync/struct.RwLock.html
126 
127 #[allow(unused_imports)]
128 #[macro_use]
129 extern crate alloc;
130 
131 pub mod access;
132 mod as_raw;
133 pub mod cache;
134 mod compile_fail_tests;
135 mod debt;
136 pub mod docs;
137 mod ref_cnt;
138 #[cfg(feature = "serde")]
139 mod serde;
140 pub mod strategy;
141 #[cfg(feature = "weak")]
142 mod weak;
143 
144 use core::borrow::Borrow;
145 use core::fmt::{Debug, Display, Formatter, Result as FmtResult};
146 use core::marker::PhantomData;
147 use core::mem;
148 use core::ops::Deref;
149 use core::ptr;
150 use core::sync::atomic::{AtomicPtr, Ordering};
151 
152 use alloc::sync::Arc;
153 
154 use crate::access::{Access, Map};
155 pub use crate::as_raw::AsRaw;
156 pub use crate::cache::Cache;
157 pub use crate::ref_cnt::RefCnt;
158 use crate::strategy::hybrid::{DefaultConfig, HybridStrategy};
159 use crate::strategy::sealed::Protected;
160 use crate::strategy::{CaS, Strategy};
161 pub use crate::strategy::{DefaultStrategy, IndependentStrategy};
162 
163 /// A temporary storage of the pointer.
164 ///
165 /// This guard object is returned from most loading methods (with the notable exception of
166 /// [`load_full`](struct.ArcSwapAny.html#method.load_full)). It dereferences to the smart pointer
167 /// loaded, so most operations are to be done using that.
168 pub struct Guard<T: RefCnt, S: Strategy<T> = DefaultStrategy> {
169     inner: S::Protected,
170 }
171 
172 impl<T: RefCnt, S: Strategy<T>> Guard<T, S> {
173     /// Converts it into the held value.
174     ///
175     /// This, on occasion, may be a tiny bit faster than cloning the Arc or whatever is being held
176     /// inside.
177     // Associated function on purpose, because of deref
178     #[allow(clippy::wrong_self_convention)]
179     #[inline]
into_inner(lease: Self) -> T180     pub fn into_inner(lease: Self) -> T {
181         lease.inner.into_inner()
182     }
183 
184     /// Create a guard for a given value `inner`.
185     ///
186     /// This can be useful on occasion to pass a specific object to code that expects or
187     /// wants to store a Guard.
188     ///
189     /// # Example
190     ///
191     /// ```rust
192     /// # use arc_swap::{ArcSwap, DefaultStrategy, Guard};
193     /// # use std::sync::Arc;
194     /// # let p = ArcSwap::from_pointee(42);
195     /// // Create two guards pointing to the same object
196     /// let g1 = p.load();
197     /// let g2 = Guard::<_, DefaultStrategy>::from_inner(Arc::clone(&*g1));
198     /// # drop(g2);
199     /// ```
from_inner(inner: T) -> Self200     pub fn from_inner(inner: T) -> Self {
201         Guard {
202             inner: S::Protected::from_inner(inner),
203         }
204     }
205 }
206 
207 impl<T: RefCnt, S: Strategy<T>> Deref for Guard<T, S> {
208     type Target = T;
209     #[inline]
deref(&self) -> &T210     fn deref(&self) -> &T {
211         self.inner.borrow()
212     }
213 }
214 
215 impl<T: RefCnt, S: Strategy<T>> From<T> for Guard<T, S> {
from(inner: T) -> Self216     fn from(inner: T) -> Self {
217         Self::from_inner(inner)
218     }
219 }
220 
221 impl<T: Default + RefCnt, S: Strategy<T>> Default for Guard<T, S> {
default() -> Self222     fn default() -> Self {
223         Self::from(T::default())
224     }
225 }
226 
227 impl<T: Debug + RefCnt, S: Strategy<T>> Debug for Guard<T, S> {
fmt(&self, formatter: &mut Formatter) -> FmtResult228     fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
229         self.deref().fmt(formatter)
230     }
231 }
232 
233 impl<T: Display + RefCnt, S: Strategy<T>> Display for Guard<T, S> {
fmt(&self, formatter: &mut Formatter) -> FmtResult234     fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
235         self.deref().fmt(formatter)
236     }
237 }
238 
239 /// Comparison of two pointer-like things.
240 // A and B are likely to *be* references, or thin wrappers around that. Calling that with extra
241 // reference is just annoying.
242 #[allow(clippy::needless_pass_by_value)]
ptr_eq<Base, A, B>(a: A, b: B) -> bool where A: AsRaw<Base>, B: AsRaw<Base>,243 fn ptr_eq<Base, A, B>(a: A, b: B) -> bool
244 where
245     A: AsRaw<Base>,
246     B: AsRaw<Base>,
247 {
248     let a = a.as_raw();
249     let b = b.as_raw();
250     ptr::eq(a, b)
251 }
252 
253 /// An atomic storage for a reference counted smart pointer like [`Arc`] or `Option<Arc>`.
254 ///
255 /// This is a storage where a smart pointer may live. It can be read and written atomically from
256 /// several threads, but doesn't act like a pointer itself.
257 ///
258 /// One can be created [`from`] an [`Arc`]. To get the pointer back, use the
259 /// [`load`](#method.load).
260 ///
261 /// # Note
262 ///
263 /// This is the common generic implementation. This allows sharing the same code for storing
264 /// both `Arc` and `Option<Arc>` (and possibly other similar types).
265 ///
266 /// In your code, you most probably want to interact with it through the
267 /// [`ArcSwap`](type.ArcSwap.html) and [`ArcSwapOption`](type.ArcSwapOption.html) aliases. However,
268 /// the methods they share are described here and are applicable to both of them. That's why the
269 /// examples here use `ArcSwap` ‒ but they could as well be written with `ArcSwapOption` or
270 /// `ArcSwapAny`.
271 ///
272 /// # Type parameters
273 ///
274 /// * `T`: The smart pointer to be kept inside. This crate provides implementation for `Arc<_>` and
275 ///   `Option<Arc<_>>` (`Rc` too, but that one is not practically useful). But third party could
276 ///   provide implementations of the [`RefCnt`] trait and plug in others.
277 /// * `S`: Chooses the [strategy] used to protect the data inside. They come with various
278 ///   performance trade offs, the default [`DefaultStrategy`] is good rule of thumb for most use
279 ///   cases.
280 ///
281 /// # Examples
282 ///
283 /// ```rust
284 /// # use std::sync::Arc;
285 /// # use arc_swap::ArcSwap;
286 /// let arc = Arc::new(42);
287 /// let arc_swap = ArcSwap::from(arc);
288 /// assert_eq!(42, **arc_swap.load());
289 /// // It can be read multiple times
290 /// assert_eq!(42, **arc_swap.load());
291 ///
292 /// // Put a new one in there
293 /// let new_arc = Arc::new(0);
294 /// assert_eq!(42, *arc_swap.swap(new_arc));
295 /// assert_eq!(0, **arc_swap.load());
296 /// ```
297 ///
298 /// # Known bugs
299 ///
300 /// Currently, things like `ArcSwapAny<Option<Option<Arc<_>>>>` (notice the double Option) don't
301 /// work properly. A proper solution is being looked into
302 /// ([#81](https://github.com/vorner/arc-swap/issues)).
303 ///
304 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
305 /// [`from`]: https://doc.rust-lang.org/nightly/std/convert/trait.From.html#tymethod.from
306 /// [`RefCnt`]: trait.RefCnt.html
307 pub struct ArcSwapAny<T: RefCnt, S: Strategy<T> = DefaultStrategy> {
308     // Notes: AtomicPtr needs Sized
309     /// The actual pointer, extracted from the Arc.
310     ptr: AtomicPtr<T::Base>,
311 
312     /// We are basically an Arc in disguise. Inherit parameters from Arc by pretending to contain
313     /// it.
314     _phantom_arc: PhantomData<T>,
315 
316     /// Strategy to protect the data.
317     strategy: S,
318 }
319 
320 impl<T: RefCnt, S: Default + Strategy<T>> From<T> for ArcSwapAny<T, S> {
from(val: T) -> Self321     fn from(val: T) -> Self {
322         Self::with_strategy(val, S::default())
323     }
324 }
325 
326 impl<T: RefCnt, S: Strategy<T>> Drop for ArcSwapAny<T, S> {
drop(&mut self)327     fn drop(&mut self) {
328         let ptr = *self.ptr.get_mut();
329         unsafe {
330             // To pay any possible debts
331             self.strategy.wait_for_readers(ptr, &self.ptr);
332             // We are getting rid of the one stored ref count
333             T::dec(ptr);
334         }
335     }
336 }
337 
338 impl<T, S: Strategy<T>> Debug for ArcSwapAny<T, S>
339 where
340     T: Debug + RefCnt,
341 {
fmt(&self, formatter: &mut Formatter) -> FmtResult342     fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
343         formatter
344             .debug_tuple("ArcSwapAny")
345             .field(&self.load())
346             .finish()
347     }
348 }
349 
350 impl<T, S: Strategy<T>> Display for ArcSwapAny<T, S>
351 where
352     T: Display + RefCnt,
353 {
fmt(&self, formatter: &mut Formatter) -> FmtResult354     fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
355         self.load().fmt(formatter)
356     }
357 }
358 
359 impl<T: RefCnt + Default, S: Default + Strategy<T>> Default for ArcSwapAny<T, S> {
default() -> Self360     fn default() -> Self {
361         Self::new(T::default())
362     }
363 }
364 
365 impl<T: RefCnt, S: Strategy<T>> ArcSwapAny<T, S> {
366     /// Constructs a new storage.
new(val: T) -> Self where S: Default,367     pub fn new(val: T) -> Self
368     where
369         S: Default,
370     {
371         Self::from(val)
372     }
373 
374     /// Constructs a new storage while customizing the protection strategy.
with_strategy(val: T, strategy: S) -> Self375     pub fn with_strategy(val: T, strategy: S) -> Self {
376         // The AtomicPtr requires *mut in its interface. We are more like *const, so we cast it.
377         // However, we always go back to *const right away when we get the pointer on the other
378         // side, so it should be fine.
379         let ptr = T::into_ptr(val);
380         Self {
381             ptr: AtomicPtr::new(ptr),
382             _phantom_arc: PhantomData,
383             strategy,
384         }
385     }
386 
387     /// Extracts the value inside.
into_inner(mut self) -> T388     pub fn into_inner(mut self) -> T {
389         let ptr = *self.ptr.get_mut();
390         // To pay all the debts
391         unsafe { self.strategy.wait_for_readers(ptr, &self.ptr) };
392         mem::forget(self);
393         unsafe { T::from_ptr(ptr) }
394     }
395 
396     /// Loads the value.
397     ///
398     /// This makes another copy of the held pointer and returns it, atomically (it is
399     /// safe even when other thread stores into the same instance at the same time).
400     ///
401     /// The method is lock-free and wait-free, but usually more expensive than
402     /// [`load`](#method.load).
load_full(&self) -> T403     pub fn load_full(&self) -> T {
404         Guard::into_inner(self.load())
405     }
406 
407     /// Provides a temporary borrow of the object inside.
408     ///
409     /// This returns a proxy object allowing access to the thing held inside. However, there's
410     /// only limited amount of possible cheap proxies in existence for each thread ‒ if more are
411     /// created, it falls back to equivalent of [`load_full`](#method.load_full) internally.
412     ///
413     /// This is therefore a good choice to use for eg. searching a data structure or juggling the
414     /// pointers around a bit, but not as something to store in larger amounts. The rule of thumb
415     /// is this is suited for local variables on stack, but not in long-living data structures.
416     ///
417     /// # Consistency
418     ///
419     /// In case multiple related operations are to be done on the loaded value, it is generally
420     /// recommended to call `load` just once and keep the result over calling it multiple times.
421     /// First, keeping it is usually faster. But more importantly, the value can change between the
422     /// calls to load, returning different objects, which could lead to logical inconsistency.
423     /// Keeping the result makes sure the same object is used.
424     ///
425     /// ```rust
426     /// # use arc_swap::ArcSwap;
427     /// struct Point {
428     ///     x: usize,
429     ///     y: usize,
430     /// }
431     ///
432     /// fn print_broken(p: &ArcSwap<Point>) {
433     ///     // This is broken, because the x and y may come from different points,
434     ///     // combining into an invalid point that never existed.
435     ///     println!("X: {}", p.load().x);
436     ///     // If someone changes the content now, between these two loads, we
437     ///     // have a problem
438     ///     println!("Y: {}", p.load().y);
439     /// }
440     ///
441     /// fn print_correct(p: &ArcSwap<Point>) {
442     ///     // Here we take a snapshot of one specific point so both x and y come
443     ///     // from the same one.
444     ///     let point = p.load();
445     ///     println!("X: {}", point.x);
446     ///     println!("Y: {}", point.y);
447     /// }
448     /// # let p = ArcSwap::from_pointee(Point { x: 10, y: 20 });
449     /// # print_correct(&p);
450     /// # print_broken(&p);
451     /// ```
452     #[inline]
load(&self) -> Guard<T, S>453     pub fn load(&self) -> Guard<T, S> {
454         let protected = unsafe { self.strategy.load(&self.ptr) };
455         Guard { inner: protected }
456     }
457 
458     /// Replaces the value inside this instance.
459     ///
460     /// Further loads will yield the new value. Uses [`swap`](#method.swap) internally.
store(&self, val: T)461     pub fn store(&self, val: T) {
462         drop(self.swap(val));
463     }
464 
465     /// Exchanges the value inside this instance.
swap(&self, new: T) -> T466     pub fn swap(&self, new: T) -> T {
467         let new = T::into_ptr(new);
468         // AcqRel needed to publish the target of the new pointer and get the target of the old
469         // one.
470         //
471         // SeqCst to synchronize the time lines with the group counters.
472         let old = self.ptr.swap(new, Ordering::SeqCst);
473         unsafe {
474             self.strategy.wait_for_readers(old, &self.ptr);
475             T::from_ptr(old)
476         }
477     }
478 
479     /// Swaps the stored Arc if it equals to `current`.
480     ///
481     /// If the current value of the `ArcSwapAny` equals to `current`, the `new` is stored inside.
482     /// If not, nothing happens.
483     ///
484     /// The previous value (no matter if the swap happened or not) is returned. Therefore, if the
485     /// returned value is equal to `current`, the swap happened. You want to do a pointer-based
486     /// comparison to determine it.
487     ///
488     /// In other words, if the caller „guesses“ the value of current correctly, it acts like
489     /// [`swap`](#method.swap), otherwise it acts like [`load_full`](#method.load_full) (including
490     /// the limitations).
491     ///
492     /// The `current` can be specified as `&Arc`, [`Guard`](struct.Guard.html),
493     /// [`&Guards`](struct.Guards.html) or as a raw pointer (but _not_ owned `Arc`). See the
494     /// [`AsRaw`] trait.
compare_and_swap<C>(&self, current: C, new: T) -> Guard<T, S> where C: AsRaw<T::Base>, S: CaS<T>,495     pub fn compare_and_swap<C>(&self, current: C, new: T) -> Guard<T, S>
496     where
497         C: AsRaw<T::Base>,
498         S: CaS<T>,
499     {
500         let protected = unsafe { self.strategy.compare_and_swap(&self.ptr, current, new) };
501         Guard { inner: protected }
502     }
503 
504     /// Read-Copy-Update of the pointer inside.
505     ///
506     /// This is useful in read-heavy situations with several threads that sometimes update the data
507     /// pointed to. The readers can just repeatedly use [`load`](#method.load) without any locking.
508     /// The writer uses this method to perform the update.
509     ///
510     /// In case there's only one thread that does updates or in case the next version is
511     /// independent of the previous one, simple [`swap`](#method.swap) or [`store`](#method.store)
512     /// is enough. Otherwise, it may be needed to retry the update operation if some other thread
513     /// made an update in between. This is what this method does.
514     ///
515     /// # Examples
516     ///
517     /// This will *not* work as expected, because between loading and storing, some other thread
518     /// might have updated the value.
519     ///
520     /// ```rust
521     /// # use std::sync::Arc;
522     /// #
523     /// # use arc_swap::ArcSwap;
524     /// # use crossbeam_utils::thread;
525     /// #
526     /// let cnt = ArcSwap::from_pointee(0);
527     /// thread::scope(|scope| {
528     ///     for _ in 0..10 {
529     ///         scope.spawn(|_| {
530     ///            let inner = cnt.load_full();
531     ///             // Another thread might have stored some other number than what we have
532     ///             // between the load and store.
533     ///             cnt.store(Arc::new(*inner + 1));
534     ///         });
535     ///     }
536     /// }).unwrap();
537     /// // This will likely fail:
538     /// // assert_eq!(10, *cnt.load_full());
539     /// ```
540     ///
541     /// This will, but it can call the closure multiple times to retry:
542     ///
543     /// ```rust
544     /// # use arc_swap::ArcSwap;
545     /// # use crossbeam_utils::thread;
546     /// #
547     /// let cnt = ArcSwap::from_pointee(0);
548     /// thread::scope(|scope| {
549     ///     for _ in 0..10 {
550     ///         scope.spawn(|_| cnt.rcu(|inner| **inner + 1));
551     ///     }
552     /// }).unwrap();
553     /// assert_eq!(10, *cnt.load_full());
554     /// ```
555     ///
556     /// Due to the retries, you might want to perform all the expensive operations *before* the
557     /// rcu. As an example, if there's a cache of some computations as a map, and the map is cheap
558     /// to clone but the computations are not, you could do something like this:
559     ///
560     /// ```rust
561     /// # use std::collections::HashMap;
562     /// #
563     /// # use arc_swap::ArcSwap;
564     /// # use once_cell::sync::Lazy;
565     /// #
566     /// fn expensive_computation(x: usize) -> usize {
567     ///     x * 2 // Let's pretend multiplication is *really expensive expensive*
568     /// }
569     ///
570     /// type Cache = HashMap<usize, usize>;
571     ///
572     /// static CACHE: Lazy<ArcSwap<Cache>> = Lazy::new(|| ArcSwap::default());
573     ///
574     /// fn cached_computation(x: usize) -> usize {
575     ///     let cache = CACHE.load();
576     ///     if let Some(result) = cache.get(&x) {
577     ///         return *result;
578     ///     }
579     ///     // Not in cache. Compute and store.
580     ///     // The expensive computation goes outside, so it is not retried.
581     ///     let result = expensive_computation(x);
582     ///     CACHE.rcu(|cache| {
583     ///         // The cheaper clone of the cache can be retried if need be.
584     ///         let mut cache = HashMap::clone(&cache);
585     ///         cache.insert(x, result);
586     ///         cache
587     ///     });
588     ///     result
589     /// }
590     ///
591     /// assert_eq!(42, cached_computation(21));
592     /// assert_eq!(42, cached_computation(21));
593     /// ```
594     ///
595     /// # The cost of cloning
596     ///
597     /// Depending on the size of cache above, the cloning might not be as cheap. You can however
598     /// use persistent data structures ‒ each modification creates a new data structure, but it
599     /// shares most of the data with the old one (which is usually accomplished by using `Arc`s
600     /// inside to share the unchanged values). Something like
601     /// [`rpds`](https://crates.io/crates/rpds) or [`im`](https://crates.io/crates/im) might do
602     /// what you need.
rcu<R, F>(&self, mut f: F) -> T where F: FnMut(&T) -> R, R: Into<T>, S: CaS<T>,603     pub fn rcu<R, F>(&self, mut f: F) -> T
604     where
605         F: FnMut(&T) -> R,
606         R: Into<T>,
607         S: CaS<T>,
608     {
609         let mut cur = self.load();
610         loop {
611             let new = f(&cur).into();
612             let prev = self.compare_and_swap(&*cur, new);
613             let swapped = ptr_eq(&*cur, &*prev);
614             if swapped {
615                 return Guard::into_inner(prev);
616             } else {
617                 cur = prev;
618             }
619         }
620     }
621 
622     /// Provides an access to an up to date projection of the carried data.
623     ///
624     /// # Motivation
625     ///
626     /// Sometimes, an application consists of components. Each component has its own configuration
627     /// structure. The whole configuration contains all the smaller config parts.
628     ///
629     /// For the sake of separation and abstraction, it is not desirable to pass the whole
630     /// configuration to each of the components. This allows the component to take only access to
631     /// its own part.
632     ///
633     /// # Lifetimes & flexibility
634     ///
635     /// This method is not the most flexible way, as the returned type borrows into the `ArcSwap`.
636     /// To provide access into eg. `Arc<ArcSwap<T>>`, you can create the [`Map`] type directly. See
637     /// the [`access`] module.
638     ///
639     /// # Performance
640     ///
641     /// As the provided function is called on each load from the shared storage, it should
642     /// generally be cheap. It is expected this will usually be just referencing of a field inside
643     /// the structure.
644     ///
645     /// # Examples
646     ///
647     /// ```rust
648     /// use std::sync::Arc;
649     ///
650     /// use arc_swap::ArcSwap;
651     /// use arc_swap::access::Access;
652     ///
653     /// struct Cfg {
654     ///     value: usize,
655     /// }
656     ///
657     /// fn print_many_times<V: Access<usize>>(value: V) {
658     ///     for _ in 0..25 {
659     ///         let value = value.load();
660     ///         println!("{}", *value);
661     ///     }
662     /// }
663     ///
664     /// let shared = ArcSwap::from_pointee(Cfg { value: 0 });
665     /// let mapped = shared.map(|c: &Cfg| &c.value);
666     /// crossbeam_utils::thread::scope(|s| {
667     ///     // Will print some zeroes and some twos
668     ///     s.spawn(|_| print_many_times(mapped));
669     ///     s.spawn(|_| shared.store(Arc::new(Cfg { value: 2 })));
670     /// }).expect("Something panicked in a thread");
671     /// ```
map<I, R, F>(&self, f: F) -> Map<&Self, I, F> where F: Fn(&I) -> &R + Clone, Self: Access<I>,672     pub fn map<I, R, F>(&self, f: F) -> Map<&Self, I, F>
673     where
674         F: Fn(&I) -> &R + Clone,
675         Self: Access<I>,
676     {
677         Map::new(self, f)
678     }
679 }
680 
681 /// An atomic storage for `Arc`.
682 ///
683 /// This is a type alias only. Most of its methods are described on
684 /// [`ArcSwapAny`](struct.ArcSwapAny.html).
685 pub type ArcSwap<T> = ArcSwapAny<Arc<T>>;
686 
687 impl<T, S: Strategy<Arc<T>>> ArcSwapAny<Arc<T>, S> {
688     /// A convenience constructor directly from the pointed-to value.
689     ///
690     /// Direct equivalent for `ArcSwap::new(Arc::new(val))`.
from_pointee(val: T) -> Self where S: Default,691     pub fn from_pointee(val: T) -> Self
692     where
693         S: Default,
694     {
695         Self::from(Arc::new(val))
696     }
697 }
698 
699 /// An atomic storage for `Option<Arc>`.
700 ///
701 /// This is very similar to [`ArcSwap`](type.ArcSwap.html), but allows storing NULL values, which
702 /// is useful in some situations.
703 ///
704 /// This is a type alias only. Most of the methods are described on
705 /// [`ArcSwapAny`](struct.ArcSwapAny.html). Even though the examples there often use `ArcSwap`,
706 /// they are applicable to `ArcSwapOption` with appropriate changes.
707 ///
708 /// # Examples
709 ///
710 /// ```
711 /// use std::sync::Arc;
712 /// use arc_swap::ArcSwapOption;
713 ///
714 /// let shared = ArcSwapOption::from(None);
715 /// assert!(shared.load_full().is_none());
716 /// assert!(shared.swap(Some(Arc::new(42))).is_none());
717 /// assert_eq!(42, **shared.load_full().as_ref().unwrap());
718 /// ```
719 pub type ArcSwapOption<T> = ArcSwapAny<Option<Arc<T>>>;
720 
721 impl<T, S: Strategy<Option<Arc<T>>>> ArcSwapAny<Option<Arc<T>>, S> {
722     /// A convenience constructor directly from a pointed-to value.
723     ///
724     /// This just allocates the `Arc` under the hood.
725     ///
726     /// # Examples
727     ///
728     /// ```rust
729     /// use arc_swap::ArcSwapOption;
730     ///
731     /// let empty: ArcSwapOption<usize> = ArcSwapOption::from_pointee(None);
732     /// assert!(empty.load().is_none());
733     /// let non_empty: ArcSwapOption<usize> = ArcSwapOption::from_pointee(42);
734     /// assert_eq!(42, **non_empty.load().as_ref().unwrap());
735     /// ```
from_pointee<V: Into<Option<T>>>(val: V) -> Self where S: Default,736     pub fn from_pointee<V: Into<Option<T>>>(val: V) -> Self
737     where
738         S: Default,
739     {
740         Self::new(val.into().map(Arc::new))
741     }
742 
743     /// A convenience constructor for an empty value.
744     ///
745     /// This is equivalent to `ArcSwapOption::new(None)`.
empty() -> Self where S: Default,746     pub fn empty() -> Self
747     where
748         S: Default,
749     {
750         Self::new(None)
751     }
752 }
753 
754 impl<T> ArcSwapOption<T> {
755     /// A const-fn equivalent of [empty].
756     ///
757     /// Just like [empty], this creates an `None`-holding `ArcSwapOption`. The [empty] is, however,
758     /// more general ‒ this is available only for the default strategy, while [empty] is for any
759     /// [Default]-constructible strategy (current or future one).
760     ///
761     /// [empty]: ArcSwapAny::empty
762     ///
763     /// # Examples
764     ///
765     /// ```rust
766     /// # use std::sync::Arc;
767     /// # use arc_swap::ArcSwapOption;
768     /// static GLOBAL_DATA: ArcSwapOption<usize> = ArcSwapOption::const_empty();
769     ///
770     /// assert!(GLOBAL_DATA.load().is_none());
771     /// GLOBAL_DATA.store(Some(Arc::new(42)));
772     /// assert_eq!(42, **GLOBAL_DATA.load().as_ref().unwrap());
773     /// ```
const_empty() -> Self774     pub const fn const_empty() -> Self {
775         Self {
776             ptr: AtomicPtr::new(ptr::null_mut()),
777             _phantom_arc: PhantomData,
778             strategy: HybridStrategy {
779                 _config: DefaultConfig,
780             },
781         }
782     }
783 }
784 
785 /// An atomic storage that doesn't share the internal generation locks with others.
786 ///
787 /// This makes it bigger and it also might suffer contention (on the HW level) if used from many
788 /// threads at once. On the other hand, it can't block writes in other instances.
789 ///
790 /// See the [`IndependentStrategy`] for further details.
791 // Being phased out. Will deprecate once we verify in production that the new strategy works fine.
792 #[doc(hidden)]
793 pub type IndependentArcSwap<T> = ArcSwapAny<Arc<T>, IndependentStrategy>;
794 
795 /// Arc swap for the [Weak] pointer.
796 ///
797 /// This is similar to [ArcSwap], but it doesn't store [Arc], it stores [Weak]. It doesn't keep the
798 /// data alive when pointed to.
799 ///
800 /// This is a type alias only. Most of the methods are described on the
801 /// [`ArcSwapAny`](struct.ArcSwapAny.html).
802 ///
803 /// Needs the `weak` feature turned on.
804 ///
805 /// [Weak]: std::sync::Weak
806 #[cfg(feature = "weak")]
807 pub type ArcSwapWeak<T> = ArcSwapAny<alloc::sync::Weak<T>>;
808 
809 macro_rules! t {
810     ($name: ident, $strategy: ty) => {
811         #[cfg(test)]
812         mod $name {
813             use alloc::borrow::ToOwned;
814             use alloc::string::String;
815             use alloc::vec::Vec;
816             use core::sync::atomic::{self, AtomicUsize};
817 
818             use adaptive_barrier::{Barrier, PanicMode};
819             use crossbeam_utils::thread;
820 
821             use super::*;
822 
823             const ITERATIONS: usize = 10;
824 
825             #[allow(deprecated)] // We use "deprecated" testing strategies in here.
826             type As<T> = ArcSwapAny<Arc<T>, $strategy>;
827             #[allow(deprecated)] // We use "deprecated" testing strategies in here.
828             type Aso<T> = ArcSwapAny<Option<Arc<T>>, $strategy>;
829 
830             /// Similar to the one in doc tests of the lib, but more times and more intensive (we
831             /// want to torture it a bit).
832             #[test]
833             #[cfg_attr(miri, ignore)] // Takes like 1 or 2 infinities to run under miri
834             fn publish() {
835                 const READERS: usize = 2;
836                 for _ in 0..ITERATIONS {
837                     let config = As::<String>::default();
838                     let ended = AtomicUsize::new(0);
839                     thread::scope(|scope| {
840                         for _ in 0..READERS {
841                             scope.spawn(|_| loop {
842                                 let cfg = config.load_full();
843                                 if !cfg.is_empty() {
844                                     assert_eq!(*cfg, "New configuration");
845                                     ended.fetch_add(1, Ordering::Relaxed);
846                                     return;
847                                 }
848                                 atomic::spin_loop_hint();
849                             });
850                         }
851                         scope.spawn(|_| {
852                             let new_conf = Arc::new("New configuration".to_owned());
853                             config.store(new_conf);
854                         });
855                     })
856                     .unwrap();
857                     assert_eq!(READERS, ended.load(Ordering::Relaxed));
858                     let arc = config.load_full();
859                     assert_eq!(2, Arc::strong_count(&arc));
860                     assert_eq!(0, Arc::weak_count(&arc));
861                 }
862             }
863 
864             /// Similar to the doc tests of ArcSwap, but happens more times.
865             #[test]
866             fn swap_load() {
867                 for _ in 0..100 {
868                     let arc = Arc::new(42);
869                     let arc_swap = As::from(Arc::clone(&arc));
870                     assert_eq!(42, **arc_swap.load());
871                     // It can be read multiple times
872                     assert_eq!(42, **arc_swap.load());
873 
874                     // Put a new one in there
875                     let new_arc = Arc::new(0);
876                     assert_eq!(42, *arc_swap.swap(Arc::clone(&new_arc)));
877                     assert_eq!(0, **arc_swap.load());
878                     // One loaded here, one in the arc_swap, one in new_arc
879                     let loaded = arc_swap.load_full();
880                     assert_eq!(3, Arc::strong_count(&loaded));
881                     assert_eq!(0, Arc::weak_count(&loaded));
882                     // The original got released from the arc_swap
883                     assert_eq!(1, Arc::strong_count(&arc));
884                     assert_eq!(0, Arc::weak_count(&arc));
885                 }
886             }
887 
888             /// Two different writers publish two series of values. The readers check that it is
889             /// always increasing in each serie.
890             ///
891             /// For performance, we try to reuse the threads here.
892             #[test]
893             fn multi_writers() {
894                 let first_value = Arc::new((0, 0));
895                 let shared = As::from(Arc::clone(&first_value));
896                 const WRITER_CNT: usize = 2;
897                 const READER_CNT: usize = 3;
898                 #[cfg(miri)]
899                 const ITERATIONS: usize = 5;
900                 #[cfg(not(miri))]
901                 const ITERATIONS: usize = 100;
902                 const SEQ: usize = 50;
903                 let barrier = Barrier::new(PanicMode::Poison);
904                 thread::scope(|scope| {
905                     for w in 0..WRITER_CNT {
906                         // We need to move w into the closure. But we want to just reference the
907                         // other things.
908                         let mut barrier = barrier.clone();
909                         let shared = &shared;
910                         let first_value = &first_value;
911                         scope.spawn(move |_| {
912                             for _ in 0..ITERATIONS {
913                                 barrier.wait();
914                                 shared.store(Arc::clone(&first_value));
915                                 barrier.wait();
916                                 for i in 0..SEQ {
917                                     shared.store(Arc::new((w, i + 1)));
918                                 }
919                             }
920                         });
921                     }
922                     for _ in 0..READER_CNT {
923                         let mut barrier = barrier.clone();
924                         let shared = &shared;
925                         let first_value = &first_value;
926                         scope.spawn(move |_| {
927                             for _ in 0..ITERATIONS {
928                                 barrier.wait();
929                                 barrier.wait();
930                                 let mut previous = [0; WRITER_CNT];
931                                 let mut last = Arc::clone(&first_value);
932                                 loop {
933                                     let cur = shared.load();
934                                     if Arc::ptr_eq(&last, &cur) {
935                                         atomic::spin_loop_hint();
936                                         continue;
937                                     }
938                                     let (w, s) = **cur;
939                                     assert!(previous[w] < s, "{:?} vs {:?}", previous, cur);
940                                     previous[w] = s;
941                                     last = Guard::into_inner(cur);
942                                     if s == SEQ {
943                                         break;
944                                     }
945                                 }
946                             }
947                         });
948                     }
949 
950                     drop(barrier);
951                 })
952                 .unwrap();
953             }
954 
955             #[test]
956             fn load_null() {
957                 let shared = Aso::<usize>::default();
958                 let guard = shared.load();
959                 assert!(guard.is_none());
960                 shared.store(Some(Arc::new(42)));
961                 assert_eq!(42, **shared.load().as_ref().unwrap());
962             }
963 
964             #[test]
965             fn from_into() {
966                 let a = Arc::new(42);
967                 let shared = As::new(a);
968                 let guard = shared.load();
969                 let a = shared.into_inner();
970                 assert_eq!(42, *a);
971                 assert_eq!(2, Arc::strong_count(&a));
972                 drop(guard);
973                 assert_eq!(1, Arc::strong_count(&a));
974             }
975 
976             // Note on the Relaxed order here. This should be enough, because there's that
977             // barrier.wait in between that should do the synchronization of happens-before for us.
978             // And using SeqCst would probably not help either, as there's nothing else with SeqCst
979             // here in this test to relate it to.
980             #[derive(Default)]
981             struct ReportDrop(Arc<AtomicUsize>);
982             impl Drop for ReportDrop {
983                 fn drop(&mut self) {
984                     self.0.fetch_add(1, Ordering::Relaxed);
985                 }
986             }
987 
988             /// Interaction of two threads about a guard and dropping it.
989             ///
990             /// We make sure everything works in timely manner (eg. dropping of stuff) even if multiple
991             /// threads interact.
992             ///
993             /// The idea is:
994             /// * Thread 1 loads a value.
995             /// * Thread 2 replaces the shared value. The original value is not destroyed.
996             /// * Thread 1 drops the guard. The value is destroyed and this is observable in both threads.
997             #[test]
998             fn guard_drop_in_thread() {
999                 for _ in 0..ITERATIONS {
1000                     let cnt = Arc::new(AtomicUsize::new(0));
1001 
1002                     let shared = As::from_pointee(ReportDrop(cnt.clone()));
1003                     assert_eq!(cnt.load(Ordering::Relaxed), 0, "Dropped prematurely");
1004                     // We need the threads to wait for each other at places.
1005                     let sync = Barrier::new(PanicMode::Poison);
1006 
1007                     thread::scope(|scope| {
1008                         scope.spawn({
1009                             let sync = sync.clone();
1010                             |_| {
1011                                 let mut sync = sync; // Move into the closure
1012                                 let guard = shared.load();
1013                                 sync.wait();
1014                                 // Thread 2 replaces the shared value. We wait for it to confirm.
1015                                 sync.wait();
1016                                 drop(guard);
1017                                 assert_eq!(cnt.load(Ordering::Relaxed), 1, "Value not dropped");
1018                                 // Let thread 2 know we already dropped it.
1019                                 sync.wait();
1020                             }
1021                         });
1022 
1023                         scope.spawn(|_| {
1024                             let mut sync = sync;
1025                             // Thread 1 loads, we wait for that
1026                             sync.wait();
1027                             shared.store(Default::default());
1028                             assert_eq!(
1029                                 cnt.load(Ordering::Relaxed),
1030                                 0,
1031                                 "Dropped while still in use"
1032                             );
1033                             // Let thread 2 know we replaced it
1034                             sync.wait();
1035                             // Thread 1 drops its guard. We wait for it to confirm.
1036                             sync.wait();
1037                             assert_eq!(cnt.load(Ordering::Relaxed), 1, "Value not dropped");
1038                         });
1039                     })
1040                     .unwrap();
1041                 }
1042             }
1043 
1044             /// Check dropping a lease in a different thread than it was created doesn't cause any
1045             /// problems.
1046             #[test]
1047             fn guard_drop_in_another_thread() {
1048                 for _ in 0..ITERATIONS {
1049                     let cnt = Arc::new(AtomicUsize::new(0));
1050                     let shared = As::from_pointee(ReportDrop(cnt.clone()));
1051                     assert_eq!(cnt.load(Ordering::Relaxed), 0, "Dropped prematurely");
1052                     let guard = shared.load();
1053 
1054                     drop(shared);
1055                     assert_eq!(cnt.load(Ordering::Relaxed), 0, "Dropped prematurely");
1056 
1057                     thread::scope(|scope| {
1058                         scope.spawn(|_| {
1059                             drop(guard);
1060                         });
1061                     })
1062                     .unwrap();
1063 
1064                     assert_eq!(cnt.load(Ordering::Relaxed), 1, "Not dropped");
1065                 }
1066             }
1067 
1068             #[test]
1069             fn load_option() {
1070                 let shared = Aso::from_pointee(42);
1071                 // The type here is not needed in real code, it's just addition test the type matches.
1072                 let opt: Option<_> = Guard::into_inner(shared.load());
1073                 assert_eq!(42, *opt.unwrap());
1074 
1075                 shared.store(None);
1076                 assert!(shared.load().is_none());
1077             }
1078 
1079             // Check stuff can get formatted
1080             #[test]
1081             fn debug_impl() {
1082                 let shared = As::from_pointee(42);
1083                 assert_eq!("ArcSwapAny(42)", &format!("{:?}", shared));
1084                 assert_eq!("42", &format!("{:?}", shared.load()));
1085             }
1086 
1087             #[test]
1088             fn display_impl() {
1089                 let shared = As::from_pointee(42);
1090                 assert_eq!("42", &format!("{}", shared));
1091                 assert_eq!("42", &format!("{}", shared.load()));
1092             }
1093 
1094             // The following "tests" are not run, only compiled. They check that things that should be
1095             // Send/Sync actually are.
1096             fn _check_stuff_is_send_sync() {
1097                 let shared = As::from_pointee(42);
1098                 let moved = As::from_pointee(42);
1099                 let shared_ref = &shared;
1100                 let lease = shared.load();
1101                 let lease_ref = &lease;
1102                 let lease = shared.load();
1103                 thread::scope(|s| {
1104                     s.spawn(move |_| {
1105                         let _ = lease;
1106                         let _ = lease_ref;
1107                         let _ = shared_ref;
1108                         let _ = moved;
1109                     });
1110                 })
1111                 .unwrap();
1112             }
1113 
1114             /// We have a callback in RCU. Check what happens if we access the value from within.
1115             #[test]
1116             fn recursive() {
1117                 let shared = ArcSwap::from(Arc::new(0));
1118 
1119                 shared.rcu(|i| {
1120                     if **i < 10 {
1121                         shared.rcu(|i| **i + 1);
1122                     }
1123                     **i
1124                 });
1125                 assert_eq!(10, **shared.load());
1126                 assert_eq!(2, Arc::strong_count(&shared.load_full()));
1127             }
1128 
1129             /// A panic from within the rcu callback should not change anything.
1130             #[test]
1131             #[cfg(not(feature = "experimental-thread-local"))]
1132             fn rcu_panic() {
1133                 use std::panic;
1134                 let shared = ArcSwap::from(Arc::new(0));
1135                 assert!(panic::catch_unwind(|| shared.rcu(|_| -> usize { panic!() })).is_err());
1136                 assert_eq!(1, Arc::strong_count(&shared.swap(Arc::new(42))));
1137             }
1138 
1139             /// Handling null/none values
1140             #[test]
1141             fn nulls() {
1142                 let shared = ArcSwapOption::from(Some(Arc::new(0)));
1143                 let orig = shared.swap(None);
1144                 assert_eq!(1, Arc::strong_count(&orig.unwrap()));
1145                 let null = shared.load();
1146                 assert!(null.is_none());
1147                 let a = Arc::new(42);
1148                 let orig = shared.compare_and_swap(ptr::null(), Some(Arc::clone(&a)));
1149                 assert!(orig.is_none());
1150                 assert_eq!(2, Arc::strong_count(&a));
1151                 let orig = Guard::into_inner(shared.compare_and_swap(&None::<Arc<_>>, None));
1152                 assert_eq!(3, Arc::strong_count(&a));
1153                 assert!(ptr_eq(&a, &orig));
1154             }
1155 
1156             #[test]
1157             /// Multiple RCUs interacting.
1158             fn rcu() {
1159                 const ITERATIONS: usize = 50;
1160                 const THREADS: usize = 10;
1161                 let shared = ArcSwap::from(Arc::new(0));
1162                 thread::scope(|scope| {
1163                     for _ in 0..THREADS {
1164                         scope.spawn(|_| {
1165                             for _ in 0..ITERATIONS {
1166                                 shared.rcu(|old| **old + 1);
1167                             }
1168                         });
1169                     }
1170                 })
1171                 .unwrap();
1172                 assert_eq!(THREADS * ITERATIONS, **shared.load());
1173             }
1174 
1175             #[test]
1176             /// Make sure the reference count and compare_and_swap works as expected.
1177             fn cas_ref_cnt() {
1178                 #[cfg(miri)]
1179                 const ITERATIONS: usize = 10;
1180                 #[cfg(not(miri))]
1181                 const ITERATIONS: usize = 50;
1182                 let shared = ArcSwap::from(Arc::new(0));
1183                 for i in 0..ITERATIONS {
1184                     let orig = shared.load_full();
1185                     assert_eq!(i, *orig);
1186                     if i % 2 == 1 {
1187                         // One for orig, one for shared
1188                         assert_eq!(2, Arc::strong_count(&orig));
1189                     }
1190                     let n1 = Arc::new(i + 1);
1191                     // Fill up the slots sometimes
1192                     let fillup = || {
1193                         if i % 2 == 0 {
1194                             Some((0..ITERATIONS).map(|_| shared.load()).collect::<Vec<_>>())
1195                         } else {
1196                             None
1197                         }
1198                     };
1199                     let guards = fillup();
1200                     // Success
1201                     let prev = shared.compare_and_swap(&orig, Arc::clone(&n1));
1202                     assert!(ptr_eq(&orig, &prev));
1203                     drop(guards);
1204                     // One for orig, one for prev
1205                     assert_eq!(2, Arc::strong_count(&orig));
1206                     // One for n1, one for shared
1207                     assert_eq!(2, Arc::strong_count(&n1));
1208                     assert_eq!(i + 1, **shared.load());
1209                     let n2 = Arc::new(i);
1210                     drop(prev);
1211                     let guards = fillup();
1212                     // Failure
1213                     let prev = Guard::into_inner(shared.compare_and_swap(&orig, Arc::clone(&n2)));
1214                     drop(guards);
1215                     assert!(ptr_eq(&n1, &prev));
1216                     // One for orig
1217                     assert_eq!(1, Arc::strong_count(&orig));
1218                     // One for n1, one for shared, one for prev
1219                     assert_eq!(3, Arc::strong_count(&n1));
1220                     // n2 didn't get increased
1221                     assert_eq!(1, Arc::strong_count(&n2));
1222                     assert_eq!(i + 1, **shared.load());
1223                 }
1224 
1225                 let a = shared.load_full();
1226                 // One inside shared, one for a
1227                 assert_eq!(2, Arc::strong_count(&a));
1228                 drop(shared);
1229                 // Only a now
1230                 assert_eq!(1, Arc::strong_count(&a));
1231             }
1232         }
1233     };
1234 }
1235 
1236 t!(tests_default, DefaultStrategy);
1237 #[cfg(all(feature = "internal-test-strategies", test))]
1238 #[allow(deprecated)]
1239 mod internal_strategies {
1240     use super::*;
1241     t!(
1242         tests_full_slots,
1243         crate::strategy::test_strategies::FillFastSlots
1244     );
1245 }
1246 
1247 /// These tests assume details about the used strategy.
1248 #[cfg(test)]
1249 mod tests {
1250     use super::*;
1251 
1252     use alloc::vec::Vec;
1253 
1254     /// Accessing the value inside ArcSwap with Guards (and checks for the reference
1255     /// counts).
1256     #[test]
load_cnt()1257     fn load_cnt() {
1258         let a = Arc::new(0);
1259         let shared = ArcSwap::from(Arc::clone(&a));
1260         // One in shared, one in a
1261         assert_eq!(2, Arc::strong_count(&a));
1262         let guard = shared.load();
1263         assert_eq!(0, **guard);
1264         // The guard doesn't have its own ref count now
1265         assert_eq!(2, Arc::strong_count(&a));
1266         let guard_2 = shared.load();
1267         // Unlike with guard, this does not deadlock
1268         shared.store(Arc::new(1));
1269         // But now, each guard got a full Arc inside it
1270         assert_eq!(3, Arc::strong_count(&a));
1271         // And when we get rid of them, they disappear
1272         drop(guard_2);
1273         assert_eq!(2, Arc::strong_count(&a));
1274         let _b = Arc::clone(&guard);
1275         assert_eq!(3, Arc::strong_count(&a));
1276         // We can drop the guard it came from
1277         drop(guard);
1278         assert_eq!(2, Arc::strong_count(&a));
1279         let guard = shared.load();
1280         assert_eq!(1, **guard);
1281         drop(shared);
1282         // We can still use the guard after the shared disappears
1283         assert_eq!(1, **guard);
1284         let ptr = Arc::clone(&guard);
1285         // One in shared, one in guard
1286         assert_eq!(2, Arc::strong_count(&ptr));
1287         drop(guard);
1288         assert_eq!(1, Arc::strong_count(&ptr));
1289     }
1290 
1291     /// There can be only limited amount of leases on one thread. Following ones are
1292     /// created, but contain full Arcs.
1293     #[test]
lease_overflow()1294     fn lease_overflow() {
1295         #[cfg(miri)]
1296         const GUARD_COUNT: usize = 100;
1297         #[cfg(not(miri))]
1298         const GUARD_COUNT: usize = 1000;
1299         let a = Arc::new(0);
1300         let shared = ArcSwap::from(Arc::clone(&a));
1301         assert_eq!(2, Arc::strong_count(&a));
1302         let mut guards = (0..GUARD_COUNT).map(|_| shared.load()).collect::<Vec<_>>();
1303         let count = Arc::strong_count(&a);
1304         assert!(count > 2);
1305         let guard = shared.load();
1306         assert_eq!(count + 1, Arc::strong_count(&a));
1307         drop(guard);
1308         assert_eq!(count, Arc::strong_count(&a));
1309         // When we delete the first one, it didn't have an Arc in it, so the ref count
1310         // doesn't drop
1311         guards.swap_remove(0);
1312         assert_eq!(count, Arc::strong_count(&a));
1313         // But new one reuses now vacant the slot and doesn't create a new Arc
1314         let _guard = shared.load();
1315         assert_eq!(count, Arc::strong_count(&a));
1316     }
1317 }
1318