@@ -35,6 +35,23 @@ impl Task {
35
35
crate :: queue:: QUEUE . with ( |queue| queue. schedule_task ( this) ) ;
36
36
}
37
37
38
+ fn force_wake ( this : Rc < Self > ) {
39
+ crate :: queue:: QUEUE . with ( |queue| {
40
+ queue. push_task ( this) ;
41
+ } ) ;
42
+ }
43
+
44
+ fn wake ( this : Rc < Self > ) {
45
+ // If we've already been placed on the run queue then there's no need to
46
+ // requeue ourselves since we're going to run at some point in the
47
+ // future anyway.
48
+ if this. is_queued . replace ( true ) {
49
+ return ;
50
+ }
51
+
52
+ Self :: force_wake ( this) ;
53
+ }
54
+
38
55
fn wake_by_ref ( this : & Rc < Self > ) {
39
56
// If we've already been placed on the run queue then there's no need to
40
57
// requeue ourselves since we're going to run at some point in the
@@ -43,9 +60,7 @@ impl Task {
43
60
return ;
44
61
}
45
62
46
- crate :: queue:: QUEUE . with ( |queue| {
47
- queue. push_task ( Rc :: clone ( this) ) ;
48
- } ) ;
63
+ Self :: force_wake ( Rc :: clone ( this) ) ;
49
64
}
50
65
51
66
/// Creates a standard library `RawWaker` from an `Rc` of ourselves.
@@ -55,15 +70,17 @@ impl Task {
55
70
/// however, everything is guaranteed to be singlethreaded (since we're
56
71
/// compiled without the `atomics` feature) so we "safely lie" and say our
57
72
/// `Rc` pointer is good enough.
73
+ ///
74
+ /// The implementation is based off of futures::task::ArcWake
58
75
unsafe fn into_raw_waker ( this : Rc < Self > ) -> RawWaker {
59
76
unsafe fn raw_clone ( ptr : * const ( ) ) -> RawWaker {
60
77
let ptr = ManuallyDrop :: new ( Rc :: from_raw ( ptr as * const Task ) ) ;
61
- Task :: into_raw_waker ( ( * ptr ) . clone ( ) )
78
+ Task :: into_raw_waker ( Rc :: clone ( & ptr ) )
62
79
}
63
80
64
81
unsafe fn raw_wake ( ptr : * const ( ) ) {
65
82
let ptr = Rc :: from_raw ( ptr as * const Task ) ;
66
- Task :: wake_by_ref ( & ptr) ;
83
+ Task :: wake ( ptr) ;
67
84
}
68
85
69
86
unsafe fn raw_wake_by_ref ( ptr : * const ( ) ) {
@@ -75,7 +92,7 @@ impl Task {
75
92
drop ( Rc :: from_raw ( ptr as * const Task ) ) ;
76
93
}
77
94
78
- const VTABLE : RawWakerVTable =
95
+ static VTABLE : RawWakerVTable =
79
96
RawWakerVTable :: new ( raw_clone, raw_wake, raw_wake_by_ref, raw_drop) ;
80
97
81
98
RawWaker :: new ( Rc :: into_raw ( this) as * const ( ) , & VTABLE )
0 commit comments