arc_swap/
lib.rs

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]
129extern crate alloc;
130
131pub mod access;
132mod as_raw;
133pub mod cache;
134mod compile_fail_tests;
135mod debt;
136pub mod docs;
137mod ref_cnt;
138#[cfg(feature = "serde")]
139mod serde;
140pub mod strategy;
141#[cfg(feature = "weak")]
142mod weak;
143
144use core::borrow::Borrow;
145use core::fmt::{Debug, Display, Formatter, Result as FmtResult};
146use core::marker::PhantomData;
147use core::mem;
148use core::ops::Deref;
149use core::ptr;
150use core::sync::atomic::{AtomicPtr, Ordering};
151
152use alloc::sync::Arc;
153
154use crate::access::{Access, Map};
155pub use crate::as_raw::AsRaw;
156pub use crate::cache::Cache;
157pub use crate::ref_cnt::RefCnt;
158use crate::strategy::hybrid::{DefaultConfig, HybridStrategy};
159use crate::strategy::sealed::Protected;
160use crate::strategy::{CaS, Strategy};
161pub 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.
168pub struct Guard<T: RefCnt, S: Strategy<T> = DefaultStrategy> {
169    inner: S::Protected,
170}
171
172impl<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]
180    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    /// ```
200    pub fn from_inner(inner: T) -> Self {
201        Guard {
202            inner: S::Protected::from_inner(inner),
203        }
204    }
205}
206
207impl<T: RefCnt, S: Strategy<T>> Deref for Guard<T, S> {
208    type Target = T;
209    #[inline]
210    fn deref(&self) -> &T {
211        self.inner.borrow()
212    }
213}
214
215impl<T: RefCnt, S: Strategy<T>> From<T> for Guard<T, S> {
216    fn from(inner: T) -> Self {
217        Self::from_inner(inner)
218    }
219}
220
221impl<T: Default + RefCnt, S: Strategy<T>> Default for Guard<T, S> {
222    fn default() -> Self {
223        Self::from(T::default())
224    }
225}
226
227impl<T: Debug + RefCnt, S: Strategy<T>> Debug for Guard<T, S> {
228    fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
229        self.deref().fmt(formatter)
230    }
231}
232
233impl<T: Display + RefCnt, S: Strategy<T>> Display for Guard<T, S> {
234    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)]
243fn ptr_eq<Base, A, B>(a: A, b: B) -> bool
244where
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
307pub 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
320impl<T: RefCnt, S: Default + Strategy<T>> From<T> for ArcSwapAny<T, S> {
321    fn from(val: T) -> Self {
322        Self::with_strategy(val, S::default())
323    }
324}
325
326impl<T: RefCnt, S: Strategy<T>> Drop for ArcSwapAny<T, S> {
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
338impl<T, S: Strategy<T>> Debug for ArcSwapAny<T, S>
339where
340    T: Debug + RefCnt,
341{
342    fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
343        formatter
344            .debug_tuple("ArcSwapAny")
345            .field(&self.load())
346            .finish()
347    }
348}
349
350impl<T, S: Strategy<T>> Display for ArcSwapAny<T, S>
351where
352    T: Display + RefCnt,
353{
354    fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
355        self.load().fmt(formatter)
356    }
357}
358
359impl<T: RefCnt + Default, S: Default + Strategy<T>> Default for ArcSwapAny<T, S> {
360    fn default() -> Self {
361        Self::new(T::default())
362    }
363}
364
365impl<T: RefCnt, S: Strategy<T>> ArcSwapAny<T, S> {
366    /// Constructs a new storage.
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.
375    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.
388    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).
403    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]
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.
461    pub fn store(&self, val: T) {
462        drop(self.swap(val));
463    }
464
465    /// Exchanges the value inside this instance.
466    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.
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.
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    /// ```
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).
685pub type ArcSwap<T> = ArcSwapAny<Arc<T>>;
686
687impl<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))`.
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/// ```
719pub type ArcSwapOption<T> = ArcSwapAny<Option<Arc<T>>>;
720
721impl<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    /// ```
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)`.
746    pub fn empty() -> Self
747    where
748        S: Default,
749    {
750        Self::new(None)
751    }
752}
753
754impl<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    /// ```
774    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)]
793pub 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")]
807pub type ArcSwapWeak<T> = ArcSwapAny<alloc::sync::Weak<T>>;
808
809macro_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
1236t!(tests_default, DefaultStrategy);
1237#[cfg(all(feature = "internal-test-strategies", test))]
1238#[allow(deprecated)]
1239mod 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)]
1249mod 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]
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]
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}