@@ -17,26 +17,41 @@ pub trait ArcWake {
17
17
///
18
18
/// Executors generally maintain a queue of "ready" tasks; `wake` should place
19
19
/// the associated task onto this queue.
20
- fn wake ( arc_self : & Arc < Self > ) ;
20
+ fn wake ( self : Arc < Self > ) {
21
+ Self :: wake_by_ref ( & self )
22
+ }
23
+
24
+ /// Indicates that the associated task is ready to make progress and should
25
+ /// be `poll`ed.
26
+ ///
27
+ /// This function can be called from an arbitrary thread, including threads which
28
+ /// did not create the `ArcWake` based `Waker`.
29
+ ///
30
+ /// Executors generally maintain a queue of "ready" tasks; `wake_by_ref` should place
31
+ /// the associated task onto this queue.
32
+ ///
33
+ /// This function is similar to `wake`, but must not consume the provided data
34
+ /// pointer.
35
+ fn wake_by_ref ( arc_self : & Arc < Self > ) ;
21
36
22
37
/// Creates a `Waker` from an Arc<T>, if T implements `ArcWake`.
23
38
///
24
39
/// If `wake()` is called on the returned `Waker`,
25
40
/// the `wake()` function that is defined inside this trait will get called.
26
41
fn into_waker ( self : Arc < Self > ) -> Waker where Self : Sized
27
42
{
28
- let ptr = Arc :: into_raw ( self ) as * const ( ) ;
43
+ let ptr = Arc :: into_raw ( self ) as * const ( ) ;
29
44
30
45
unsafe {
31
- Waker :: new_unchecked ( RawWaker :: new ( ptr, waker_vtable ! ( Self ) ) )
46
+ Waker :: from_raw ( RawWaker :: new ( ptr, waker_vtable ! ( Self ) ) )
32
47
}
33
48
}
34
49
}
35
50
36
51
// FIXME: panics on Arc::clone / refcount changes could wreak havoc on the
37
52
// code here. We should guard against this by aborting.
38
53
39
- unsafe fn increase_refcount < T : ArcWake > ( data : * const ( ) ) {
54
+ unsafe fn increase_refcount < T : ArcWake > ( data : * const ( ) ) {
40
55
// Retain Arc by creating a copy
41
56
let arc: Arc < T > = Arc :: from_raw ( data as * const T ) ;
42
57
let arc_clone = arc. clone ( ) ;
@@ -46,19 +61,25 @@ unsafe fn increase_refcount<T: ArcWake>(data: *const()) {
46
61
}
47
62
48
63
// used by `waker_ref`
49
- pub ( super ) unsafe fn clone_arc_raw < T : ArcWake > ( data : * const ( ) ) -> RawWaker {
64
+ pub ( super ) unsafe fn clone_arc_raw < T : ArcWake > ( data : * const ( ) ) -> RawWaker {
50
65
increase_refcount :: < T > ( data) ;
51
66
RawWaker :: new ( data, waker_vtable ! ( T ) )
52
67
}
53
68
54
- unsafe fn drop_arc_raw < T : ArcWake > ( data : * const ( ) ) {
69
+ unsafe fn drop_arc_raw < T : ArcWake > ( data : * const ( ) ) {
55
70
drop ( Arc :: < T > :: from_raw ( data as * const T ) )
56
71
}
57
72
58
73
// used by `waker_ref`
59
- pub ( super ) unsafe fn wake_arc_raw < T : ArcWake > ( data : * const ( ) ) {
74
+ pub ( super ) unsafe fn wake_arc_raw < T : ArcWake > ( data : * const ( ) ) {
75
+ let arc: Arc < T > = Arc :: from_raw ( data as * const T ) ;
76
+ ArcWake :: wake ( arc) ;
77
+ }
78
+
79
+ // used by `waker_ref`
80
+ pub ( super ) unsafe fn wake_by_ref_arc_raw < T : ArcWake > ( data : * const ( ) ) {
60
81
let arc: Arc < T > = Arc :: from_raw ( data as * const T ) ;
61
- ArcWake :: wake ( & arc) ;
82
+ ArcWake :: wake_by_ref ( & arc) ;
62
83
mem:: forget ( arc) ;
63
84
}
64
85
@@ -84,7 +105,7 @@ mod tests {
84
105
}
85
106
86
107
impl ArcWake for CountingWaker {
87
- fn wake ( arc_self : & Arc < Self > ) {
108
+ fn wake_by_ref ( arc_self : & Arc < Self > ) {
88
109
let mut lock = arc_self. nr_wake . lock ( ) . unwrap ( ) ;
89
110
* lock += 1 ;
90
111
}
@@ -96,13 +117,13 @@ mod tests {
96
117
97
118
let w1: Waker = ArcWake :: into_waker ( some_w. clone ( ) ) ;
98
119
assert_eq ! ( 2 , Arc :: strong_count( & some_w) ) ;
99
- w1. wake ( ) ;
120
+ w1. wake_by_ref ( ) ;
100
121
assert_eq ! ( 1 , some_w. wakes( ) ) ;
101
122
102
123
let w2 = w1. clone ( ) ;
103
124
assert_eq ! ( 3 , Arc :: strong_count( & some_w) ) ;
104
125
105
- w2. wake ( ) ;
126
+ w2. wake_by_ref ( ) ;
106
127
assert_eq ! ( 2 , some_w. wakes( ) ) ;
107
128
108
129
drop ( w2) ;
0 commit comments