Skip to content

Commit e597a6c

Browse files
taiki-ecramertj
authored andcommitted
Change ArcWake::into_waker to a free function
1 parent 55e4827 commit e597a6c

File tree

9 files changed

+81
-77
lines changed

9 files changed

+81
-77
lines changed

futures-test/src/task/wake_counter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use futures_core::task::{Waker};
1+
use futures_core::task::Waker;
2+
use futures_util::task::{self, ArcWake};
23
use std::sync::Arc;
34
use std::sync::atomic::{AtomicUsize, Ordering};
4-
use futures_util::task::ArcWake;
55

66
/// Number of times the waker was awoken.
77
///
@@ -55,5 +55,5 @@ impl ArcWake for WakerInner {
5555
/// ```
5656
pub fn new_count_waker() -> (Waker, AwokenCount) {
5757
let inner = Arc::new(WakerInner { count: AtomicUsize::new(0) });
58-
(ArcWake::into_waker(inner.clone()), AwokenCount { inner })
58+
(task::waker(inner.clone()), AwokenCount { inner })
5959
}

futures-util/src/compat/compat03as01.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ use futures_01::{
77
AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01,
88
};
99
use futures_core::{
10-
task::{
11-
self as task03,
12-
RawWaker,
13-
RawWakerVTable,
14-
},
10+
task::{RawWaker, RawWakerVTable},
1511
TryFuture as TryFuture03,
1612
TryStream as TryStream03,
1713
};
1814
#[cfg(feature = "sink")]
1915
use futures_sink::Sink as Sink03;
20-
use crate::task::{ArcWake as ArcWake03, WakerRef};
16+
use crate::task::{
17+
self as task03,
18+
ArcWake as ArcWake03,
19+
WakerRef,
20+
};
2121
#[cfg(feature = "sink")]
2222
use std::marker::PhantomData;
2323
use std::{
@@ -85,7 +85,7 @@ impl<T, Item> CompatSink<T, Item> {
8585
_phantom: PhantomData,
8686
}
8787
}
88-
88+
8989
/// Get a reference to 0.3 Sink contained within.
9090
pub fn get_ref(&self) -> &T {
9191
&self.inner
@@ -192,7 +192,7 @@ impl Current {
192192
// FIXME: remove `transmute` when a `Waker` -> `RawWaker` conversion
193193
// function is landed in `core`.
194194
mem::transmute::<task03::Waker, RawWaker>(
195-
Arc::new(ptr_to_current(ptr).clone()).into_waker()
195+
task03::waker(Arc::new(ptr_to_current(ptr).clone()))
196196
)
197197
}
198198
unsafe fn drop(_: *const ()) {}

futures-util/src/task/arc_wake.rs

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use core::mem;
2-
use core::task::{Waker, RawWaker, RawWakerVTable};
31
use alloc::sync::Arc;
42

53
/// A way of waking up a specific task.
@@ -35,52 +33,4 @@ pub trait ArcWake: Send + Sync {
3533
/// This function is similar to `wake`, but must not consume the provided data
3634
/// pointer.
3735
fn wake_by_ref(arc_self: &Arc<Self>);
38-
39-
/// Creates a `Waker` from an Arc<T>, if T implements `ArcWake`.
40-
///
41-
/// If `wake()` is called on the returned `Waker`,
42-
/// the `wake()` function that is defined inside this trait will get called.
43-
fn into_waker(self: Arc<Self>) -> Waker where Self: Sized
44-
{
45-
let ptr = Arc::into_raw(self) as *const ();
46-
47-
unsafe {
48-
Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self)))
49-
}
50-
}
51-
}
52-
53-
// FIXME: panics on Arc::clone / refcount changes could wreak havoc on the
54-
// code here. We should guard against this by aborting.
55-
56-
unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
57-
// Retain Arc by creating a copy
58-
let arc: Arc<T> = Arc::from_raw(data as *const T);
59-
let arc_clone = arc.clone();
60-
// Forget the Arcs again, so that the refcount isn't decrased
61-
mem::forget(arc);
62-
mem::forget(arc_clone);
63-
}
64-
65-
// used by `waker_ref`
66-
pub(super) unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
67-
increase_refcount::<T>(data);
68-
RawWaker::new(data, waker_vtable!(T))
69-
}
70-
71-
unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
72-
drop(Arc::<T>::from_raw(data as *const T))
73-
}
74-
75-
// used by `waker_ref`
76-
pub(super) unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
77-
let arc: Arc<T> = Arc::from_raw(data as *const T);
78-
ArcWake::wake(arc);
79-
}
80-
81-
// used by `waker_ref`
82-
pub(super) unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
83-
let arc: Arc<T> = Arc::from_raw(data as *const T);
84-
ArcWake::wake_by_ref(&arc);
85-
mem::forget(arc);
8636
}

futures-util/src/task/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ cfg_target_has_atomic! {
2020
#[cfg(feature = "alloc")]
2121
pub use self::arc_wake::ArcWake;
2222

23+
#[cfg(feature = "alloc")]
24+
mod waker;
25+
#[cfg(feature = "alloc")]
26+
pub use self::waker::waker;
27+
2328
#[cfg(feature = "alloc")]
2429
mod waker_ref;
2530
#[cfg(feature = "alloc")]

futures-util/src/task/noop_waker.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn noop_raw_waker() -> RawWaker {
1616
RawWaker::new(null(), &NOOP_WAKER_VTABLE)
1717
}
1818

19-
/// Create a new [`Waker`](futures_core::task::Waker) which does
19+
/// Create a new [`Waker`] which does
2020
/// nothing when `wake()` is called on it.
2121
///
2222
/// # Examples
@@ -33,7 +33,7 @@ pub fn noop_waker() -> Waker {
3333
}
3434
}
3535

36-
/// Get a static reference to a [`Waker`](futures_core::task::Waker) which
36+
/// Get a static reference to a [`Waker`] which
3737
/// does nothing when `wake()` is called on it.
3838
///
3939
/// # Examples

futures-util/src/task/waker.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use super::arc_wake::ArcWake;
2+
use core::mem;
3+
use core::task::{Waker, RawWaker, RawWakerVTable};
4+
use alloc::sync::Arc;
5+
6+
/// Creates a [`Waker`] from an `Arc<impl ArcWake>`.
7+
///
8+
/// The returned [`Waker`] will call
9+
/// [`ArcWake.wake()`](ArcWake::wake) if awoken.
10+
pub fn waker<W>(wake: Arc<W>) -> Waker
11+
where
12+
W: ArcWake,
13+
{
14+
let ptr = Arc::into_raw(wake) as *const ();
15+
16+
unsafe {
17+
Waker::from_raw(RawWaker::new(ptr, waker_vtable!(W)))
18+
}
19+
}
20+
21+
// FIXME: panics on Arc::clone / refcount changes could wreak havoc on the
22+
// code here. We should guard against this by aborting.
23+
24+
unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
25+
// Retain Arc by creating a copy
26+
let arc: Arc<T> = Arc::from_raw(data as *const T);
27+
let arc_clone = arc.clone();
28+
// Forget the Arcs again, so that the refcount isn't decrased
29+
mem::forget(arc);
30+
mem::forget(arc_clone);
31+
}
32+
33+
// used by `waker_ref`
34+
pub(super) unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
35+
increase_refcount::<T>(data);
36+
RawWaker::new(data, waker_vtable!(T))
37+
}
38+
39+
unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
40+
let arc: Arc<T> = Arc::from_raw(data as *const T);
41+
ArcWake::wake(arc);
42+
}
43+
44+
// used by `waker_ref`
45+
pub(super) unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
46+
let arc: Arc<T> = Arc::from_raw(data as *const T);
47+
ArcWake::wake_by_ref(&arc);
48+
mem::forget(arc);
49+
}
50+
51+
unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
52+
drop(Arc::<T>::from_raw(data as *const T))
53+
}

futures-util/src/task/waker_ref.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
#![allow(clippy::cast_ptr_alignment)] // clippy is too strict here
2-
3-
use super::arc_wake::{ArcWake, clone_arc_raw, wake_by_ref_arc_raw};
1+
use super::arc_wake::ArcWake;
2+
use super::waker::{clone_arc_raw, wake_by_ref_arc_raw};
43
use alloc::sync::Arc;
54
use core::marker::PhantomData;
65
use core::ops::Deref;
76
use core::task::{Waker, RawWaker, RawWakerVTable};
87

9-
// TODO: The link to Waker below points to futures::task::Waker and not to std. Is that a
10-
// bug in rustdoc?
11-
//
12-
/// A [`Waker`](::std::task::Waker) that is only valid for a given lifetime.
8+
/// A [`Waker`] that is only valid for a given lifetime.
139
///
14-
/// Note: this type implements [`Deref<Target = Waker>`](::std::ops::Deref),
10+
/// Note: this type implements [`Deref<Target = Waker>`](std::ops::Deref),
1511
/// so it can be used to get a `&Waker`.
1612
#[derive(Debug)]
1713
pub struct WakerRef<'a> {
@@ -56,10 +52,9 @@ unsafe fn wake_unreachable(_data: *const ()) {
5652
unreachable!("WakerRef::wake");
5753
}
5854

59-
/// Creates a reference to a [`Waker`](::std::task::Waker)
60-
/// from a local [`ArcWake`].
55+
/// Creates a reference to a [`Waker`] from a reference to `Arc<impl ArcWake>`.
6156
///
62-
/// The resulting [`Waker`](::std::task::Waker) will call
57+
/// The resulting [`Waker`] will call
6358
/// [`ArcWake.wake()`](ArcWake::wake) if awoken.
6459
#[inline]
6560
pub fn waker_ref<W>(wake: &Arc<W>) -> WakerRef<'_>
@@ -68,6 +63,7 @@ where
6863
{
6964
// This uses the same mechanism as Arc::into_raw, without needing a reference.
7065
// This is potentially not stable
66+
#![allow(clippy::cast_ptr_alignment)]
7167
let ptr = &*wake as &W as *const W as *const ();
7268

7369
// Similar to `waker_vtable`, but with a no-op `drop` function.

futures/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ pub mod task {
491491
cfg(all(target_has_atomic = "cas", target_has_atomic = "ptr"))
492492
)]
493493
#[cfg(feature = "alloc")]
494-
pub use futures_util::task::{WakerRef, waker_ref, ArcWake};
494+
pub use futures_util::task::{waker, waker_ref, WakerRef, ArcWake};
495495

496496
#[cfg_attr(
497497
feature = "cfg-target-has-atomic",

futures/tests/arc_wake.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use futures::task::{ArcWake, Waker};
1+
use futures::task::{self, ArcWake, Waker};
22
use std::sync::{Arc, Mutex};
33

44
struct CountingWaker {
@@ -28,7 +28,7 @@ impl ArcWake for CountingWaker {
2828
fn create_waker_from_arc() {
2929
let some_w = Arc::new(CountingWaker::new());
3030

31-
let w1: Waker = ArcWake::into_waker(some_w.clone());
31+
let w1: Waker = task::waker(some_w.clone());
3232
assert_eq!(2, Arc::strong_count(&some_w));
3333
w1.wake_by_ref();
3434
assert_eq!(1, some_w.wakes());

0 commit comments

Comments
 (0)