//! Thread-safe reference-counting pointers.
//!
//! See the [`Arc<T>`][Arc] documentation for more details.
+//!
+//! **Note**: This module is only available on platforms that support atomic
+//! loads and stores of pointers. This may be detected at compile time using
+//! `#[cfg(target_has_atomic = "ptr")]`.
use core::any::Any;
use core::borrow;
#[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;
/// [`Mutex`][mutex], [`RwLock`][rwlock], or one of the [`Atomic`][atomic]
/// types.
///
+/// **Note**: This type is only available on platforms that support atomic
+/// loads and stores of pointers, which includes all platforms that support
+/// the `std` crate but not all those which only support [`alloc`](crate).
+/// This may be detected at compile time using `#[cfg(target_has_atomic = "ptr")]`.
+///
/// ## Thread Safety
///
/// Unlike [`Rc<T>`], `Arc<T>` uses atomic operations for its reference
/// let five = Arc::clone(&five);
///
/// thread::spawn(move || {
-/// println!("{:?}", five);
+/// println!("{five:?}");
/// });
/// }
/// ```
///
/// thread::spawn(move || {
/// let v = val.fetch_add(1, Ordering::SeqCst);
-/// println!("{:?}", v);
+/// println!("{v:?}");
/// });
/// }
/// ```
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}
impl<T: ?Sized> Arc<T> {
- fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
+ unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
Self { ptr, phantom: PhantomData }
}
#[stable(feature = "arc_weak", since = "1.4.0")]
unsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
data: T,
}
+/// Calculate layout for `ArcInner<T>` using the inner value's layout
+fn arcinner_layout_for_value_layout(layout: Layout) -> Layout {
+ // Calculate layout using the given value layout.
+ // Previously, layout was calculated on the expression
+ // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
+ // reference (see #54908).
+ Layout::new::<ArcInner<()>>().extend(layout).unwrap().0.pad_to_align()
+}
+
unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}
pub fn new(data: T) -> Arc<T> {
// Start the weak pointer count as 1 which is the weak pointer that's
// held by all the strong pointers (kinda), see std/rc.rs for more info
- let x: Box<_> = box ArcInner {
+ let x: Box<_> = Box::new(ArcInner {
strong: atomic::AtomicUsize::new(1),
weak: atomic::AtomicUsize::new(1),
data,
- };
- Self::from_inner(Box::leak(x).into())
+ });
+ unsafe { Self::from_inner(Box::leak(x).into()) }
}
- /// Constructs a new `Arc<T>` using a weak reference to itself. Attempting
- /// to upgrade the weak reference before this function returns will result
- /// in a `None` value. However, the weak reference may be cloned freely and
- /// stored for use at a later time.
+ /// 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.
///
- /// # Examples
- /// ```
- /// #![feature(arc_new_cyclic)]
- /// #![allow(dead_code)]
+ /// Generally, a structure circularly referencing itself, either directly or
+ /// 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`.
+ ///
+ /// `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)]
/// use std::sync::{Arc, Weak};
///
- /// struct Foo {
- /// me: Weak<Foo>,
+ /// struct Gadget {
+ /// me: Weak<Gadget>,
/// }
///
- /// let foo = Arc::new_cyclic(|me| Foo {
- /// me: me.clone(),
- /// });
+ /// impl Gadget {
+ /// /// Construct a reference counted Gadget.
+ /// fn new() -> Arc<Self> {
+ /// // `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.
+ /// fn me(&self) -> Arc<Self> {
+ /// self.me.upgrade().unwrap()
+ /// }
+ /// }
/// ```
+ /// [`upgrade`]: Weak::upgrade
#[cfg(not(no_global_oom_handling))]
#[inline]
- #[unstable(feature = "arc_new_cyclic", issue = "75861")]
- pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Arc<T> {
+ #[stable(feature = "arc_new_cyclic", since = "1.60.0")]
+ pub fn new_cyclic<F>(data_fn: F) -> Arc<T>
+ where
+ F: FnOnce(&Weak<T>) -> T,
+ {
// Construct the inner in the "uninitialized" state with a single
// weak reference.
- let uninit_ptr: NonNull<_> = Box::leak(box ArcInner {
+ let uninit_ptr: NonNull<_> = Box::leak(Box::new(ArcInner {
strong: atomic::AtomicUsize::new(0),
weak: atomic::AtomicUsize::new(1),
data: mem::MaybeUninit::<T>::uninit(),
- })
+ }))
.into();
let init_ptr: NonNull<ArcInner<T>> = uninit_ptr.cast();
// Now we can properly initialize the inner value and turn our weak
// reference into a strong reference.
- unsafe {
+ let strong = unsafe {
let inner = init_ptr.as_ptr();
ptr::write(ptr::addr_of_mut!((*inner).data), data);
// possible with safe code alone.
let prev_value = (*inner).strong.fetch_add(1, Release);
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
- }
- let strong = Arc::from_inner(init_ptr);
+ Arc::from_inner(init_ptr)
+ };
// Strong references should collectively own a shared weak reference,
// so don't run the destructor for our old weak reference.
///
/// let mut five = Arc::<u32>::new_uninit();
///
- /// let five = unsafe {
- /// // Deferred initialization:
- /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+ /// // Deferred initialization:
+ /// Arc::get_mut(&mut five).unwrap().write(5);
///
- /// five.assume_init()
- /// };
+ /// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5)
/// ```
weak: atomic::AtomicUsize::new(1),
data,
})?;
- Ok(Self::from_inner(Box::leak(x).into()))
+ unsafe { Ok(Self::from_inner(Box::leak(x).into())) }
}
/// Constructs a new `Arc` with uninitialized contents, returning an error
///
/// let mut five = Arc::<u32>::try_new_uninit()?;
///
- /// let five = unsafe {
- /// // Deferred initialization:
- /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+ /// // Deferred initialization:
+ /// Arc::get_mut(&mut five).unwrap().write(5);
///
- /// five.assume_init()
- /// };
+ /// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5);
/// # Ok::<(), std::alloc::AllocError>(())
///
/// let mut values = Arc::<[u32]>::new_uninit_slice(3);
///
- /// let values = unsafe {
- /// // Deferred initialization:
- /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
- /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
- /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+ /// // Deferred initialization:
+ /// let data = Arc::get_mut(&mut values).unwrap();
+ /// data[0].write(1);
+ /// data[1].write(2);
+ /// data[2].write(3);
///
- /// values.assume_init()
- /// };
+ /// let values = unsafe { values.assume_init() };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
///
/// let mut five = Arc::<u32>::new_uninit();
///
- /// let five = unsafe {
- /// // Deferred initialization:
- /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+ /// // Deferred initialization:
+ /// Arc::get_mut(&mut five).unwrap().write(5);
///
- /// five.assume_init()
- /// };
+ /// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5)
/// ```
#[must_use = "`self` will be dropped if the result is not used"]
#[inline]
pub unsafe fn assume_init(self) -> Arc<T> {
- Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+ unsafe { Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast()) }
}
}
///
/// let mut values = Arc::<[u32]>::new_uninit_slice(3);
///
- /// let values = unsafe {
- /// // Deferred initialization:
- /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
- /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
- /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+ /// // Deferred initialization:
+ /// let data = Arc::get_mut(&mut values).unwrap();
+ /// data[0].write(1);
+ /// data[1].write(2);
+ /// data[2].write(3);
///
- /// values.assume_init()
- /// };
+ /// let values = unsafe { values.assume_init() };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
/// let x_ptr = Arc::into_raw(x);
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// ```
+ #[must_use = "losing the pointer will leak memory"]
#[stable(feature = "rc_raw", since = "1.17.0")]
pub fn into_raw(this: Self) -> *const T {
let ptr = Self::as_ptr(&this);
let offset = data_offset(ptr);
// Reverse the offset to find the original ArcInner.
- let arc_ptr = (ptr as *mut ArcInner<T>).set_ptr_value((ptr as *mut u8).offset(-offset));
+ let arc_ptr = ptr.byte_sub(offset) as *mut ArcInner<T>;
Self::from_ptr(arc_ptr)
}
/// assert_eq!(1, Arc::weak_count(&five));
/// ```
#[inline]
+ #[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 }
/// assert_eq!(2, Arc::strong_count(&five));
/// ```
#[inline]
+ #[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
drop(Weak { ptr: self.ptr });
}
- #[inline]
- #[stable(feature = "ptr_eq", since = "1.17.0")]
- /// Returns `true` if the two `Arc`s point to the same allocation
- /// (in a vein similar to [`ptr::eq`]).
+ /// Returns `true` if the two `Arc`s point to the same allocation in a vein similar to
+ /// [`ptr::eq`]. See [that function][`ptr::eq`] for caveats when comparing `dyn Trait` pointers.
///
/// # Examples
///
/// ```
///
/// [`ptr::eq`]: core::ptr::eq "ptr::eq"
+ #[inline]
+ #[must_use]
+ #[stable(feature = "ptr_eq", since = "1.17.0")]
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
this.ptr.as_ptr() == other.ptr.as_ptr()
}
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
) -> *mut ArcInner<T> {
- // Calculate layout using the given value layout.
- // Previously, layout was calculated on the expression
- // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
- // reference (see #54908).
- let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();
+ let layout = arcinner_layout_for_value_layout(value_layout);
unsafe {
Arc::try_allocate_for_layout(value_layout, allocate, mem_to_arcinner)
.unwrap_or_else(|_| handle_alloc_error(layout))
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
) -> Result<*mut ArcInner<T>, AllocError> {
- // Calculate layout using the given value layout.
- // Previously, layout was calculated on the expression
- // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
- // reference (see #54908).
- let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();
+ let layout = arcinner_layout_for_value_layout(value_layout);
let ptr = allocate(layout)?;
Self::allocate_for_layout(
Layout::for_value(&*ptr),
|layout| Global.allocate(layout),
- |mem| (ptr as *mut ArcInner<T>).set_ptr_value(mem) as *mut ArcInner<T>,
+ |mem| mem.with_metadata_of(ptr as *const ArcInner<T>),
)
}
}
}
}
- /// Copy elements from slice into newly allocated Arc<\[T\]>
+ /// Copy elements from slice into newly allocated `Arc<[T]>`
///
/// Unsafe because the caller must either take ownership or bind `T: Copy`.
#[cfg(not(no_global_oom_handling))]
// [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
let old_size = self.inner().strong.fetch_add(1, Relaxed);
- // However we need to guard against massive refcounts in case someone
- // is `mem::forget`ing Arcs. If we don't do this the count can overflow
- // and users will use-after free. We racily saturate to `isize::MAX` on
- // the assumption that there aren't ~2 billion threads incrementing
- // the reference count at once. This branch will never be taken in
- // any realistic program.
+ // However we need to guard against massive refcounts in case someone is `mem::forget`ing
+ // Arcs. If we don't do this the count can overflow and users will use-after free. This
+ // branch will never be taken in any realistic program. We abort because such a program is
+ // incredibly degenerate, and we don't care to support it.
//
- // We abort because such a program is incredibly degenerate, and we
- // don't care to support it.
+ // This check is not 100% water-proof: we error when the refcount grows beyond `isize::MAX`.
+ // But we do that check *after* having done the increment, so there is a chance here that
+ // the worst already happened and we actually do overflow the `usize` counter. However, that
+ // requires the counter to grow from `isize::MAX` to `usize::MAX` between the increment
+ // above and the `abort` below, which seems exceedingly unlikely.
if old_size > MAX_REFCOUNT {
abort();
}
- Self::from_inner(self.ptr)
+ unsafe { Self::from_inner(self.ptr) }
}
}
/// referred to as clone-on-write.
///
/// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`]
- /// pointers, then the [`Weak`] pointers will be disassociated and the inner value will not
+ /// pointers, then the [`Weak`] pointers will be dissociated and the inner value will not
/// be cloned.
///
/// See also [`get_mut`], which will fail rather than cloning the inner value
- /// or diassociating [`Weak`] pointers.
+ /// or dissociating [`Weak`] pointers.
///
/// [`clone`]: Clone::clone
/// [`get_mut`]: Arc::get_mut
/// assert_eq!(*other_data, 12);
/// ```
///
- /// [`Weak`] pointers will be disassociated:
+ /// [`Weak`] pointers will be dissociated:
///
/// ```
/// use std::sync::Arc;
// either unique to begin with, or became one upon cloning the contents.
unsafe { Self::get_mut_unchecked(this) }
}
+
+ /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
+ /// clone.
+ ///
+ /// Assuming `arc_t` is of type `Arc<T>`, this function is functionally equivalent to
+ /// `(*arc_t).clone()`, but will avoid cloning the inner value where possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(arc_unwrap_or_clone)]
+ /// # use std::{ptr, sync::Arc};
+ /// let inner = String::from("test");
+ /// let ptr = inner.as_ptr();
+ ///
+ /// let arc = Arc::new(inner);
+ /// let inner = Arc::unwrap_or_clone(arc);
+ /// // The inner value was not cloned
+ /// assert!(ptr::eq(ptr, inner.as_ptr()));
+ ///
+ /// let arc = Arc::new(inner);
+ /// let arc2 = arc.clone();
+ /// let inner = Arc::unwrap_or_clone(arc);
+ /// // Because there were 2 references, we had to clone the inner value.
+ /// assert!(!ptr::eq(ptr, inner.as_ptr()));
+ /// // `arc2` is the last reference, so when we unwrap it we get back
+ /// // the original `String`.
+ /// let inner = Arc::unwrap_or_clone(arc2);
+ /// assert!(ptr::eq(ptr, inner.as_ptr()));
+ /// ```
+ #[inline]
+ #[unstable(feature = "arc_unwrap_or_clone", issue = "93610")]
+ pub fn unwrap_or_clone(this: Self) -> T {
+ Arc::try_unwrap(this).unwrap_or_else(|arc| (*arc).clone())
+ }
}
impl<T: ?Sized> Arc<T> {
///
/// # Safety
///
- /// Any other `Arc` or [`Weak`] pointers to the same allocation must not be dereferenced
- /// for the duration of the returned borrow.
- /// This is trivially the case if no such pointers exist,
- /// for example immediately after `Arc::new`.
+ /// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then
+ /// they must be must not be dereferenced or have active borrows for the duration
+ /// of the returned borrow, and their inner type must be exactly the same as the
+ /// inner type of this Rc (including lifetimes). This is trivially the case if no
+ /// such pointers exist, for example immediately after `Arc::new`.
///
/// # Examples
///
/// }
/// assert_eq!(*x, "foo");
/// ```
+ /// Other `Arc` pointers to the same allocation must be to the same type.
+ /// ```no_run
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let x: Arc<str> = Arc::from("Hello, world!");
+ /// let mut y: Arc<[u8]> = x.clone().into();
+ /// unsafe {
+ /// // this is Undefined Behavior, because x's inner type is str, not [u8]
+ /// Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
+ /// }
+ /// println!("{}", &*x); // Invalid UTF-8 in a str
+ /// ```
+ /// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes.
+ /// ```no_run
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let x: Arc<&str> = Arc::new("Hello, world!");
+ /// {
+ /// let s = String::from("Oh, no!");
+ /// let mut y: Arc<&str> = x.clone().into();
+ /// unsafe {
+ /// // this is Undefined Behavior, because x's inner type
+ /// // is &'long str, not &'short str
+ /// *Arc::get_mut_unchecked(&mut y) = &s;
+ /// }
+ /// }
+ /// println!("{}", &*x); // Use-after-free
+ /// ```
#[inline]
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
}
impl Arc<dyn Any + Send + Sync> {
- #[inline]
- #[stable(feature = "rc_downcast", since = "1.29.0")]
/// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
///
/// # Examples
/// print_if_string(Arc::new(my_string));
/// print_if_string(Arc::new(0i8));
/// ```
+ #[inline]
+ #[stable(feature = "rc_downcast", since = "1.29.0")]
pub fn downcast<T>(self) -> Result<Arc<T>, Self>
where
- T: Any + Send + Sync + 'static,
+ T: Any + Send + Sync,
{
if (*self).is::<T>() {
- let ptr = self.ptr.cast::<ArcInner<T>>();
- mem::forget(self);
- Ok(Arc::from_inner(ptr))
+ unsafe {
+ let ptr = self.ptr.cast::<ArcInner<T>>();
+ mem::forget(self);
+ Ok(Arc::from_inner(ptr))
+ }
} else {
Err(self)
}
}
+
+ /// Downcasts the `Arc<dyn Any + Send + Sync>` to a concrete type.
+ ///
+ /// For a safe alternative see [`downcast`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(downcast_unchecked)]
+ ///
+ /// use std::any::Any;
+ /// use std::sync::Arc;
+ ///
+ /// let x: Arc<dyn Any + Send + Sync> = Arc::new(1_usize);
+ ///
+ /// unsafe {
+ /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
+ /// }
+ /// ```
+ ///
+ /// # Safety
+ ///
+ /// The contained value must be of type `T`. Calling this method
+ /// with the incorrect type is *undefined behavior*.
+ ///
+ ///
+ /// [`downcast`]: Self::downcast
+ #[inline]
+ #[unstable(feature = "downcast_unchecked", issue = "90850")]
+ pub unsafe fn downcast_unchecked<T>(self) -> Arc<T>
+ where
+ T: Any + Send + Sync,
+ {
+ unsafe {
+ let ptr = self.ptr.cast::<ArcInner<T>>();
+ mem::forget(self);
+ Arc::from_inner(ptr)
+ }
+ }
}
impl<T> Weak<T> {
/// assert!(empty.upgrade().is_none());
/// ```
#[stable(feature = "downgraded_weak", since = "1.10.0")]
+ #[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")]
#[must_use]
- pub fn new() -> Weak<T> {
- Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner<T>).expect("MAX is not 0") }
+ pub const fn new() -> Weak<T> {
+ Weak { ptr: unsafe { NonNull::new_unchecked(ptr::invalid_mut::<ArcInner<T>>(usize::MAX)) } }
}
}
// a valid payload address, as the payload is at least as aligned as ArcInner (usize).
ptr as *const T
} else {
- // SAFETY: if is_dangling returns false, then the pointer is dereferencable.
+ // SAFETY: if is_dangling returns false, then the pointer is dereferenceable.
// The payload may be dropped at this point, and we have to maintain provenance,
// so use raw pointer manipulation.
unsafe { ptr::addr_of_mut!((*ptr).data) }
let offset = unsafe { data_offset(ptr) };
// Thus, we reverse the offset to get the whole RcBox.
// SAFETY: the pointer originated from a Weak, so this offset is safe.
- unsafe { (ptr as *mut ArcInner<T>).set_ptr_value((ptr as *mut u8).offset(-offset)) }
+ unsafe { ptr.byte_sub(offset) as *mut ArcInner<T> }
};
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
// We use a CAS loop to increment the strong count instead of a
// fetch_add as this function should never take the reference count
// from zero to one.
- let inner = self.inner()?;
-
- // Relaxed load because any write of 0 that we can observe
- // leaves the field in a permanently zero state (so a
- // "stale" read of 0 is fine), and any other value is
- // confirmed via the CAS below.
- let mut n = inner.strong.load(Relaxed);
-
- loop {
- if n == 0 {
- return None;
- }
-
- // See comments in `Arc::clone` for why we do this (for `mem::forget`).
- if n > MAX_REFCOUNT {
- abort();
- }
-
+ self.inner()?
+ .strong
// Relaxed is fine for the failure case because we don't have any expectations about the new state.
// Acquire is necessary for the success case to synchronise with `Arc::new_cyclic`, when the inner
// value can be initialized after `Weak` references have already been created. In that case, we
// expect to observe the fully initialized value.
- match inner.strong.compare_exchange_weak(n, n + 1, Acquire, Relaxed) {
- Ok(_) => return Some(Arc::from_inner(self.ptr)), // null checked above
- Err(old) => n = old,
- }
- }
+ .fetch_update(Acquire, Relaxed, |n| {
+ // Any write of 0 we can observe leaves the field in permanently zero state.
+ if n == 0 {
+ return None;
+ }
+ // See comments in `Arc::clone` for why we do this (for `mem::forget`).
+ if n > MAX_REFCOUNT {
+ abort();
+ }
+ Some(n + 1)
+ })
+ .ok()
+ // null checked above
+ .map(|_| unsafe { Arc::from_inner(self.ptr) })
}
/// Gets the number of strong (`Arc`) pointers pointing to this allocation.
///
/// If `self` was created using [`Weak::new`], this will return 0.
+ #[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
/// Due to implementation details, the returned value can be off by 1 in
/// either direction when other threads are manipulating any `Arc`s or
/// `Weak`s pointing to the same allocation.
+ #[must_use]
#[stable(feature = "weak_counts", since = "1.41.0")]
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 {
}
}
- /// Returns `true` if the two `Weak`s point to the same allocation (similar to
- /// [`ptr::eq`]), or if both don't point to any allocation
- /// (because they were created with `Weak::new()`).
+ /// Returns `true` if the two `Weak`s point to the same allocation similar to [`ptr::eq`], or if
+ /// both don't point to any allocation (because they were created with `Weak::new()`). See [that
+ /// function][`ptr::eq`] for caveats when comparing `dyn Trait` pointers.
///
/// # Notes
///
///
/// [`ptr::eq`]: core::ptr::eq "ptr::eq"
#[inline]
+ #[must_use]
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
pub fn ptr_eq(&self, other: &Self) -> bool {
self.ptr.as_ptr() == other.ptr.as_ptr()
#[inline]
fn from(mut v: Vec<T>) -> Arc<[T]> {
unsafe {
- let arc = Arc::copy_from_slice(&v);
-
+ let rc = Arc::copy_from_slice(&v);
// Allow the Vec to free its memory, but not destroy its contents
v.set_len(0);
-
- arc
+ rc
}
}
}
}
}
+#[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]>;
///
/// The pointer must point to (and have valid metadata for) a previously
/// valid instance of T, but the T is allowed to be dropped.
-unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
+unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> usize {
// Align the unsized value to the end of the ArcInner.
// Because RcBox is repr(C), it will always be the last field in memory.
// SAFETY: since the only unsized types possible are slices, trait objects,
}
#[inline]
-fn data_offset_align(align: usize) -> isize {
+fn data_offset_align(align: usize) -> usize {
let layout = Layout::new::<ArcInner<()>>();
- (layout.size() + layout.padding_needed_for(align)) as isize
+ layout.size() + layout.padding_needed_for(align)
+}
+
+#[stable(feature = "arc_error", since = "1.52.0")]
+impl<T: core::error::Error + ?Sized> core::error::Error for Arc<T> {
+ #[allow(deprecated, deprecated_in_future)]
+ fn description(&self) -> &str {
+ core::error::Error::description(&**self)
+ }
+
+ #[allow(deprecated)]
+ fn cause(&self) -> Option<&dyn core::error::Error> {
+ core::error::Error::cause(&**self)
+ }
+
+ fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
+ core::error::Error::source(&**self)
+ }
+
+ fn provide<'a>(&'a self, req: &mut core::any::Demand<'a>) {
+ core::error::Error::provide(&**self, req);
+ }
}