#[cfg(not(no_global_oom_handling))]
use core::slice::from_raw_parts_mut;
use core::sync::atomic;
-use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
+use core::sync::atomic::Ordering::{Acquire, Relaxed, Release};
#[cfg(not(no_global_oom_handling))]
use crate::alloc::handle_alloc_error;
unsafe { Self::from_inner(Box::leak(x).into()) }
}
- /// Constructs a new `Arc<T>` using a closure `data_fn` that has access to
- /// a weak reference to the constructing `Arc<T>`.
+ /// Constructs a new `Arc<T>` while giving you a `Weak<T>` to the allocation,
+ /// to allow you to construct a `T` which holds a weak pointer to itself.
///
/// Generally, a structure circularly referencing itself, either directly or
- /// indirectly, should not hold a strong reference to prevent a memory leak.
- /// In `data_fn`, initialization of `T` can make use of the weak reference
- /// by cloning and storing it inside `T` for use at a later time.
+ /// indirectly, should not hold a strong reference to itself to prevent a memory leak.
+ /// Using this function, you get access to the weak pointer during the
+ /// initialization of `T`, before the `Arc<T>` is created, such that you can
+ /// clone and store it inside the `T`.
///
- /// Since the new `Arc<T>` is not fully-constructed until
- /// `Arc<T>::new_cyclic` returns, calling [`upgrade`] on the weak
- /// reference inside `data_fn` will fail and result in a `None` value.
+ /// `new_cyclic` first allocates the managed allocation for the `Arc<T>`,
+ /// then calls your closure, giving it a `Weak<T>` to this allocation,
+ /// and only afterwards completes the construction of the `Arc<T>` by placing
+ /// the `T` returned from your closure into the allocation.
+ ///
+ /// Since the new `Arc<T>` is not fully-constructed until `Arc<T>::new_cyclic`
+ /// returns, calling [`upgrade`] on the weak reference inside your closure will
+ /// fail and result in a `None` value.
///
/// # Panics
+ ///
/// If `data_fn` panics, the panic is propagated to the caller, and the
/// temporary [`Weak<T>`] is dropped normally.
///
/// # Example
+ ///
/// ```
- /// #![allow(dead_code)]
+ /// # #![allow(dead_code)]
/// use std::sync::{Arc, Weak};
///
/// struct Gadget {
/// impl Gadget {
/// /// Construct a reference counted Gadget.
/// fn new() -> Arc<Self> {
- /// Arc::new_cyclic(|me| Gadget { me: me.clone() })
+ /// // `me` is a `Weak<Gadget>` pointing at the new allocation of the
+ /// // `Arc` we're constructing.
+ /// Arc::new_cyclic(|me| {
+ /// // Create the actual struct here.
+ /// Gadget { me: me.clone() }
+ /// })
/// }
///
/// /// Return a reference counted pointer to Self.
#[must_use]
#[stable(feature = "arc_counts", since = "1.15.0")]
pub fn weak_count(this: &Self) -> usize {
- let cnt = this.inner().weak.load(SeqCst);
+ let cnt = this.inner().weak.load(Acquire);
// If the weak count is currently locked, the value of the
// count was 0 just before taking the lock.
if cnt == usize::MAX { 0 } else { cnt - 1 }
#[must_use]
#[stable(feature = "arc_counts", since = "1.15.0")]
pub fn strong_count(this: &Self) -> usize {
- this.inner().strong.load(SeqCst)
+ this.inner().strong.load(Acquire)
}
/// Increments the strong reference count on the `Arc<T>` associated with the
#[must_use]
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
- if let Some(inner) = self.inner() { inner.strong.load(SeqCst) } else { 0 }
+ if let Some(inner) = self.inner() { inner.strong.load(Acquire) } else { 0 }
}
/// Gets an approximation of the number of `Weak` pointers pointing to this
pub fn weak_count(&self) -> usize {
self.inner()
.map(|inner| {
- let weak = inner.weak.load(SeqCst);
- let strong = inner.strong.load(SeqCst);
+ let weak = inner.weak.load(Acquire);
+ let strong = inner.strong.load(Acquire);
if strong == 0 {
0
} else {
}
}
+#[stable(feature = "shared_from_str", since = "1.62.0")]
+impl From<Arc<str>> for Arc<[u8]> {
+ /// Converts an atomically reference-counted string slice into a byte slice.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use std::sync::Arc;
+ /// let string: Arc<str> = Arc::from("eggplant");
+ /// let bytes: Arc<[u8]> = Arc::from(string);
+ /// assert_eq!("eggplant".as_bytes(), bytes.as_ref());
+ /// ```
+ #[inline]
+ fn from(rc: Arc<str>) -> Self {
+ // SAFETY: `str` has the same layout as `[u8]`.
+ unsafe { Arc::from_raw(Arc::into_raw(rc) as *const [u8]) }
+ }
+}
+
#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]> {
type Error = Arc<[T]>;