wake.rs.html -- source
Description: Source to the Rust file `src/libcore/task/wake.rs`.
Keywords: rust, rustlang, rust-lang

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162

    #![unstable(feature = "futures_api",
                reason = "futures in libcore are unstable",
                issue = "50547")]

    use fmt;
    use marker::Unpin;

    /// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
    /// which provides customized wakeup behavior.
    ///
    /// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
    ///
    /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
    /// customizes the behavior of the `RawWaker`.
    #[derive(PartialEq, Debug)]
    pub struct RawWaker {
        /// A data pointer, which can be used to store arbitrary data as required
        /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
        /// that is associated with the task.
        /// The value of this field gets passed to all functions that are part of
        /// the vtable as the first parameter.
        data: *const (),
        /// Virtual function pointer table that customizes the behavior of this waker.
        vtable: &'static RawWakerVTable,
    }

    impl RawWaker {
        /// Creates a new `RawWaker` from the provided `data` pointer and `vtable`.
        ///
        /// The `data` pointer can be used to store arbitrary data as required
        /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
        /// that is associated with the task.
        /// The value of this poiner will get passed to all functions that are part
        /// of the `vtable` as the first parameter.
        ///
        /// The `vtable` customizes the behavior of a `Waker` which gets created
        /// from a `RawWaker`. For each operation on the `Waker`, the associated
        /// function in the `vtable` of the underlying `RawWaker` will be called.
        pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
            RawWaker {
                data,
                vtable,
            }
        }
    }

    /// A virtual function pointer table (vtable) that specifies the behavior
    /// of a [`RawWaker`].
    ///
    /// The pointer passed to all functions inside the vtable is the `data` pointer
    /// from the enclosing [`RawWaker`] object.
    ///
    /// The functions inside this struct are only intended be called on the `data`
    /// pointer of a properly constructed [`RawWaker`] object from inside the
    /// [`RawWaker`] implementation. Calling one of the contained functions using
    /// any other `data` pointer will cause undefined behavior.
    #[derive(PartialEq, Copy, Clone, Debug)]
    pub struct RawWakerVTable {
        /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
        /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
        ///
        /// The implementation of this function must retain all resources that are
        /// required for this additional instance of a [`RawWaker`] and associated
        /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
        /// of the same task that would have been awoken by the original [`RawWaker`].
        pub clone: unsafe fn(*const ()) -> RawWaker,

        /// This function will be called when `wake` is called on the [`Waker`].
        /// It must wake up the task associated with this [`RawWaker`].
        ///
        /// The implemention of this function must not consume the provided data
        /// pointer.
        pub wake: unsafe fn(*const ()),

        /// This function gets called when a [`RawWaker`] gets dropped.
        ///
        /// The implementation of this function must make sure to release any
        /// resources that are associated with this instance of a [`RawWaker`] and
        /// associated task.
        pub drop: unsafe fn(*const ()),
    }

    /// A `Waker` is a handle for waking up a task by notifying its executor that it
    /// is ready to be run.
    ///
    /// This handle encapsulates a [`RawWaker`] instance, which defines the
    /// executor-specific wakeup behavior.
    ///
    /// Implements [`Clone`], [`Send`], and [`Sync`].
    #[repr(transparent)]
    pub struct Waker {
        waker: RawWaker,
    }

    impl Unpin for Waker {}
    unsafe impl Send for Waker {}
    unsafe impl Sync for Waker {}

    impl Waker {
        /// Wake up the task associated with this `Waker`.
        pub fn wake(&self) {
            // The actual wakeup call is delegated through a virtual function call
            // to the implementation which is defined by the executor.

            // SAFETY: This is safe because `Waker::new_unchecked` is the only way
            // to initialize `wake` and `data` requiring the user to acknowledge
            // that the contract of `RawWaker` is upheld.
            unsafe { (self.waker.vtable.wake)(self.waker.data) }
        }

        /// Returns whether or not this `Waker` and other `Waker` have awaken the same task.
        ///
        /// This function works on a best-effort basis, and may return false even
        /// when the `Waker`s would awaken the same task. However, if this function
        /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
        ///
        /// This function is primarily used for optimization purposes.
        pub fn will_wake(&self, other: &Waker) -> bool {
            self.waker == other.waker
        }

        /// Creates a new `Waker` from [`RawWaker`].
        ///
        /// The behavior of the returned `Waker` is undefined if the contract defined
        /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
        /// Therefore this method is unsafe.
        pub unsafe fn new_unchecked(waker: RawWaker) -> Waker {
            Waker {
                waker,
            }
        }
    }

    impl Clone for Waker {
        fn clone(&self) -> Self {
            Waker {
                // SAFETY: This is safe because `Waker::new_unchecked` is the only way
                // to initialize `clone` and `data` requiring the user to acknowledge
                // that the contract of [`RawWaker`] is upheld.
                waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
            }
        }
    }

    impl Drop for Waker {
        fn drop(&mut self) {
            // SAFETY: This is safe because `Waker::new_unchecked` is the only way
            // to initialize `drop` and `data` requiring the user to acknowledge
            // that the contract of `RawWaker` is upheld.
            unsafe { (self.waker.vtable.drop)(self.waker.data) }
        }
    }

    impl fmt::Debug for Waker {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
            f.debug_struct("Waker")
                .field("data", &self.waker.data)
                .field("vtable", &vtable_ptr)
                .finish()
        }
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g., `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g., `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g., `str,u8` or `String,struct:Vec,test`)