5
5
use fmt;
6
6
use marker:: Unpin ;
7
7
8
- /// A `RawWaker` allows the implementor of a task executor to create a `Waker`
8
+ /// A `RawWaker` allows the implementor of a task executor to create a [ `Waker`]
9
9
/// which provides customized wakeup behavior.
10
10
///
11
11
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
12
12
///
13
13
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
14
14
/// customizes the behavior of the `RawWaker`.
15
- #[ derive( PartialEq ) ]
15
+ #[ derive( PartialEq , Debug ) ]
16
16
pub struct RawWaker {
17
17
/// A data pointer, which can be used to store arbitrary data as required
18
18
/// by the executor. This could be e.g. a type-erased pointer to an `Arc`
@@ -24,55 +24,41 @@ pub struct RawWaker {
24
24
pub vtable : & ' static RawWakerVTable ,
25
25
}
26
26
27
- impl fmt:: Debug for RawWaker {
28
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
29
- f. debug_struct ( "RawWaker" )
30
- . finish ( )
31
- }
32
- }
33
-
34
27
/// A virtual function pointer table (vtable) that specifies the behavior
35
28
/// of a [`RawWaker`].
36
29
///
37
30
/// The pointer passed to all functions inside the vtable is the `data` pointer
38
- /// from the enclosing `RawWaker` object.
39
- #[ derive( PartialEq , Copy , Clone ) ]
31
+ /// from the enclosing [ `RawWaker`] object.
32
+ #[ derive( PartialEq , Copy , Clone , Debug ) ]
40
33
pub struct RawWakerVTable {
41
- /// This function will be called when the `RawWaker` gets cloned, e.g. when
42
- /// the `Waker` in which the `RawWaker` is stored gets cloned.
34
+ /// This function will be called when the [ `RawWaker`] gets cloned, e.g. when
35
+ /// the [ `Waker`] in which the [ `RawWaker`] is stored gets cloned.
43
36
///
44
37
/// The implementation of this function must retain all resources that are
45
- /// required for this additional instance of a `RawWaker` and associated
46
- /// task. Calling `wake` on the resulting `RawWaker` should result in a wakeup
47
- /// of the same task that would have been awoken by the original `RawWaker`.
38
+ /// required for this additional instance of a [ `RawWaker`] and associated
39
+ /// task. Calling `wake` on the resulting [ `RawWaker`] should result in a wakeup
40
+ /// of the same task that would have been awoken by the original [ `RawWaker`] .
48
41
pub clone : unsafe fn ( * const ( ) ) -> RawWaker ,
49
42
50
- /// This function will be called when `wake` is called on the `Waker`.
51
- /// It must wake up the task associated with this `RawWaker`.
43
+ /// This function will be called when `wake` is called on the [ `Waker`] .
44
+ /// It must wake up the task associated with this [ `RawWaker`] .
52
45
pub wake : unsafe fn ( * const ( ) ) ,
53
46
54
- /// This function gets called when a `RawWaker` gets dropped.
47
+ /// This function gets called when a [ `RawWaker`] gets dropped.
55
48
///
56
49
/// The implementation of this function must make sure to release any
57
- /// resources that are associated with this instance of a `RawWaker` and
50
+ /// resources that are associated with this instance of a [ `RawWaker`] and
58
51
/// associated task.
59
- pub drop_fn : unsafe fn ( * const ( ) ) ,
60
- }
61
-
62
- impl fmt:: Debug for RawWakerVTable {
63
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
64
- f. debug_struct ( "RawWakerVTable" )
65
- . finish ( )
66
- }
52
+ pub drop : unsafe fn ( * const ( ) ) ,
67
53
}
68
54
69
55
/// A `Waker` is a handle for waking up a task by notifying its executor that it
70
56
/// is ready to be run.
71
57
///
72
- /// This handle encapsulates a `RawWaker` instance, which defines the
58
+ /// This handle encapsulates a [ `RawWaker`] instance, which defines the
73
59
/// executor-specific wakeup behavior.
74
60
///
75
- /// Implements `Clone`, `Send`, and `Sync`.
61
+ /// Implements [ `Clone`], [ `Send`] , and [ `Sync`] .
76
62
#[ repr( transparent) ]
77
63
pub struct Waker {
78
64
waker : RawWaker ,
@@ -87,6 +73,10 @@ impl Waker {
87
73
pub fn wake ( & self ) {
88
74
// The actual wakeup call is delegated through a virtual function call
89
75
// to the implementation which is defined by the executor.
76
+
77
+ // SAFETY: This is safe because `Waker::new_unchecked` is the only way
78
+ // to initialize `wake` and `data` requiring the user to acknowledge
79
+ // that the contract of `RawWaker` is upheld.
90
80
unsafe { ( self . waker . vtable . wake ) ( self . waker . data ) }
91
81
}
92
82
@@ -101,10 +91,11 @@ impl Waker {
101
91
self . waker == other. waker
102
92
}
103
93
104
- /// Creates a new `Waker` from `RawWaker`.
94
+ /// Creates a new `Waker` from [ `RawWaker`] .
105
95
///
106
- /// The method cannot check whether `RawWaker` fulfills the required API
107
- /// contract to make it usable for `Waker` and is therefore unsafe.
96
+ /// The behavior of the returned `Waker` is undefined if the contract defined
97
+ /// in [RawWaker]'s documentation is not upheld. Therefore this method is
98
+ /// unsafe.
108
99
pub unsafe fn new_unchecked ( waker : RawWaker ) -> Waker {
109
100
Waker {
110
101
waker,
@@ -115,14 +106,20 @@ impl Waker {
115
106
impl Clone for Waker {
116
107
fn clone ( & self ) -> Self {
117
108
Waker {
109
+ // SAFETY: This is safe because `Waker::new_unchecked` is the only way
110
+ // to initialize `clone` and `data` requiring the user to acknowledge
111
+ // that the contract of [`RawWaker`] is upheld.
118
112
waker : unsafe { ( self . waker . vtable . clone ) ( self . waker . data ) } ,
119
113
}
120
114
}
121
115
}
122
116
123
117
impl Drop for Waker {
124
118
fn drop ( & mut self ) {
125
- unsafe { ( self . waker . vtable . drop_fn ) ( self . waker . data ) }
119
+ // SAFETY: This is safe because `Waker::new_unchecked` is the only way
120
+ // to initialize `drop` and `data` requiring the user to acknowledge
121
+ // that the contract of `RawWaker` is upheld.
122
+ unsafe { ( self . waker . vtable . drop ) ( self . waker . data ) }
126
123
}
127
124
}
128
125
0 commit comments