Skip to content

Commit

Permalink
Rollup merge of #79285 - yoshuawuyts:stabilize-arc_mutate_strong_coun…
Browse files Browse the repository at this point in the history
…t, r=m-ou-se

Stabilize Arc::{increment,decrement}_strong_count

Tracking issue: #71983

Stabilizes `Arc::{incr,decr}_strong_count`, enabling unsafely incrementing an decrementing the Arc strong count directly with fewer gotchas. This API was first introduced on nightly six months ago, and has not seen any changes since. The initial PR showed two existing pieces of code that would benefit from this API, and included a change inside the stdlib to use this.

Given the small surface area, predictable use, and no changes since introduction, I'd like to propose we stabilize this.

closes #71983
r? `@Mark-Simulacrum`

## Links
 * [Initial implementation](#70733)
 * [Motivation from #68700](#68700 (comment))
 * [Real world example in an executor](https://docs.rs/extreme/666.666.666666/src/extreme/lib.rs.html#13)
  • Loading branch information
jonas-schievink authored Jan 31, 2021
2 parents 1bf1305 + fe4ac95 commit ac37c32
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 13 deletions.
18 changes: 7 additions & 11 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,15 +962,13 @@ impl<T: ?Sized> Arc<T> {
/// # Examples
///
/// ```
/// #![feature(arc_mutate_strong_count)]
///
/// use std::sync::Arc;
///
/// let five = Arc::new(5);
///
/// unsafe {
/// let ptr = Arc::into_raw(five);
/// Arc::incr_strong_count(ptr);
/// Arc::increment_strong_count(ptr);
///
/// // This assertion is deterministic because we haven't shared
/// // the `Arc` between threads.
Expand All @@ -979,8 +977,8 @@ impl<T: ?Sized> Arc<T> {
/// }
/// ```
#[inline]
#[unstable(feature = "arc_mutate_strong_count", issue = "71983")]
pub unsafe fn incr_strong_count(ptr: *const T) {
#[stable(feature = "arc_mutate_strong_count", since = "1.51.0")]
pub unsafe fn increment_strong_count(ptr: *const T) {
// Retain Arc, but don't touch refcount by wrapping in ManuallyDrop
let arc = unsafe { mem::ManuallyDrop::new(Arc::<T>::from_raw(ptr)) };
// Now increase refcount, but don't drop new refcount either
Expand All @@ -1001,27 +999,25 @@ impl<T: ?Sized> Arc<T> {
/// # Examples
///
/// ```
/// #![feature(arc_mutate_strong_count)]
///
/// use std::sync::Arc;
///
/// let five = Arc::new(5);
///
/// unsafe {
/// let ptr = Arc::into_raw(five);
/// Arc::incr_strong_count(ptr);
/// Arc::increment_strong_count(ptr);
///
/// // Those assertions are deterministic because we haven't shared
/// // the `Arc` between threads.
/// let five = Arc::from_raw(ptr);
/// assert_eq!(2, Arc::strong_count(&five));
/// Arc::decr_strong_count(ptr);
/// Arc::decrement_strong_count(ptr);
/// assert_eq!(1, Arc::strong_count(&five));
/// }
/// ```
#[inline]
#[unstable(feature = "arc_mutate_strong_count", issue = "71983")]
pub unsafe fn decr_strong_count(ptr: *const T) {
#[stable(feature = "arc_mutate_strong_count", since = "1.51.0")]
pub unsafe fn decrement_strong_count(ptr: *const T) {
unsafe { mem::drop(Arc::from_raw(ptr)) };
}

Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
// Increment the reference count of the arc to clone it.
unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
unsafe { Arc::incr_strong_count(waker as *const W) };
unsafe { Arc::increment_strong_count(waker as *const W) };
RawWaker::new(
waker as *const (),
&RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
Expand All @@ -83,7 +83,7 @@ fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {

// Decrement the reference count of the Arc on drop
unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) {
unsafe { Arc::decr_strong_count(waker as *const W) };
unsafe { Arc::decrement_strong_count(waker as *const W) };
}

RawWaker::new(
Expand Down

0 comments on commit ac37c32

Please sign in to comment.