about summary refs log tree commit diff
path: root/src/liballoc/task.rs
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-05-07 21:46:06 +0200
committerGitHub <noreply@github.com>2020-05-07 21:46:06 +0200
commit5e9b3720e5c49656b78a047922bbc34fe74a67b3 (patch)
treeef2d032fd29a4102f02e5c9e4dc841e191b38b74 /src/liballoc/task.rs
parenta08c47310c7d49cbdc5d7afb38408ba519967ecd (diff)
parentb04599ff8405d476a05b83839c67e9aea3c640cb (diff)
downloadrust-5e9b3720e5c49656b78a047922bbc34fe74a67b3.tar.gz
rust-5e9b3720e5c49656b78a047922bbc34fe74a67b3.zip
Rollup merge of #70733 - yoshuawuyts:arc-increment-refcount, r=Mark-Simulacrum
Add Arc::{incr,decr}_strong_count

This adds two `unsafe` methods to `Arc`: `incr_strong_count` and `decr_strong_count`. A suggestion to add methods to change the strong count in `Arc` came up in during review in https://github.com/rust-lang/rust/pull/68700#discussion_r396169064, and from asking a few people this seemed like generally useful to have.

References:
- [Motivation from #68700](https://github.com/rust-lang/rust/pull/68700#discussion_r396169064)
- [Real world example in an executor](https://docs.rs/extreme/666.666.666666/src/extreme/lib.rs.html#13)
Diffstat (limited to 'src/liballoc/task.rs')
-rw-r--r--src/liballoc/task.rs12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs
index a64d5d7a63b..745444a152e 100644
--- a/src/liballoc/task.rs
+++ b/src/liballoc/task.rs
@@ -1,6 +1,6 @@
 #![unstable(feature = "wake_trait", issue = "69912")]
 //! Types and Traits for working with asynchronous tasks.
-use core::mem::{self, ManuallyDrop};
+use core::mem::ManuallyDrop;
 use core::task::{RawWaker, RawWakerVTable, Waker};
 
 use crate::sync::Arc;
@@ -60,9 +60,11 @@ 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 {
-        let waker: Arc<W> = Arc::from_raw(waker as *const W);
-        mem::forget(Arc::clone(&waker));
-        raw_waker(waker)
+        Arc::incr_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>),
+        )
     }
 
     // Wake by value, moving the Arc into the Wake::wake function
@@ -79,7 +81,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 ()) {
-        mem::drop(Arc::from_raw(waker as *const W));
+        Arc::decr_strong_count(waker as *const W);
     }
 
     RawWaker::new(