55use fmt;
66use marker:: Unpin ;
77
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`]
99/// which provides customized wakeup behavior.
1010///
1111/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
1212///
1313/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
1414/// customizes the behavior of the `RawWaker`.
15- #[ derive( PartialEq ) ]
15+ #[ derive( PartialEq , Debug ) ]
1616pub struct RawWaker {
1717 /// A data pointer, which can be used to store arbitrary data as required
1818 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
@@ -24,55 +24,41 @@ pub struct RawWaker {
2424 pub vtable : & ' static RawWakerVTable ,
2525}
2626
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-
3427/// A virtual function pointer table (vtable) that specifies the behavior
3528/// of a [`RawWaker`].
3629///
3730/// 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 ) ]
4033pub 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.
4336 ///
4437 /// 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`] .
4841 pub clone : unsafe fn ( * const ( ) ) -> RawWaker ,
4942
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`] .
5245 pub wake : unsafe fn ( * const ( ) ) ,
5346
54- /// This function gets called when a `RawWaker` gets dropped.
47+ /// This function gets called when a [ `RawWaker`] gets dropped.
5548 ///
5649 /// 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
5851 /// 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 ( ) ) ,
6753}
6854
6955/// A `Waker` is a handle for waking up a task by notifying its executor that it
7056/// is ready to be run.
7157///
72- /// This handle encapsulates a `RawWaker` instance, which defines the
58+ /// This handle encapsulates a [ `RawWaker`] instance, which defines the
7359/// executor-specific wakeup behavior.
7460///
75- /// Implements `Clone`, `Send`, and `Sync`.
61+ /// Implements [ `Clone`], [ `Send`] , and [ `Sync`] .
7662#[ repr( transparent) ]
7763pub struct Waker {
7864 waker : RawWaker ,
@@ -87,6 +73,10 @@ impl Waker {
8773 pub fn wake ( & self ) {
8874 // The actual wakeup call is delegated through a virtual function call
8975 // 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.
9080 unsafe { ( self . waker . vtable . wake ) ( self . waker . data ) }
9181 }
9282
@@ -101,10 +91,11 @@ impl Waker {
10191 self . waker == other. waker
10292 }
10393
104- /// Creates a new `Waker` from `RawWaker`.
94+ /// Creates a new `Waker` from [ `RawWaker`] .
10595 ///
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.
10899 pub unsafe fn new_unchecked ( waker : RawWaker ) -> Waker {
109100 Waker {
110101 waker,
@@ -115,14 +106,20 @@ impl Waker {
115106impl Clone for Waker {
116107 fn clone ( & self ) -> Self {
117108 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.
118112 waker : unsafe { ( self . waker . vtable . clone ) ( self . waker . data ) } ,
119113 }
120114 }
121115}
122116
123117impl Drop for Waker {
124118 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 ) }
126123 }
127124}
128125
0 commit comments