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