2018-05-30 18:23:10 -07:00
|
|
|
#![unstable(feature = "futures_api",
|
|
|
|
reason = "futures in libcore are unstable",
|
|
|
|
issue = "50547")]
|
|
|
|
|
2018-10-01 15:16:06 -07:00
|
|
|
use fmt;
|
2018-06-29 19:33:16 -07:00
|
|
|
use marker::Unpin;
|
2019-01-29 19:02:42 -08:00
|
|
|
|
|
|
|
/// A `RawWaker` allows the implementor of a task executor to create a `Waker`
|
|
|
|
/// which provides customized wakeup behavior.
|
|
|
|
///
|
|
|
|
/// It consists of a data pointer and a virtual function pointer table (vtable) that
|
|
|
|
/// customizes the behavior of the `RawWaker`.
|
|
|
|
#[derive(PartialEq)]
|
|
|
|
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 first parameter.
|
|
|
|
pub data: *const (),
|
|
|
|
/// Virtual function pointer table that customizes the behavior of this waker.
|
|
|
|
pub vtable: &'static RawWakerVTable,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for RawWaker {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("RawWaker")
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
|
|
|
#[derive(PartialEq, Copy, Clone)]
|
|
|
|
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`.
|
|
|
|
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_fn: unsafe fn(*const ()),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for RawWakerVTable {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("RawWakerVTable")
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
2018-06-08 16:45:27 -04:00
|
|
|
|
2018-05-30 18:23:10 -07:00
|
|
|
/// A `Waker` is a handle for waking up a task by notifying its executor that it
|
|
|
|
/// is ready to be run.
|
|
|
|
///
|
2019-01-29 19:02:42 -08:00
|
|
|
/// This handle encapsulates a `RawWaker` instance, which defines the
|
|
|
|
/// executor-specific wakeup behavior.
|
|
|
|
///
|
|
|
|
/// Implements `Clone`, `Send`, and `Sync`.
|
2018-05-30 18:23:10 -07:00
|
|
|
#[repr(transparent)]
|
|
|
|
pub struct Waker {
|
2019-01-29 19:02:42 -08:00
|
|
|
waker: RawWaker,
|
2018-05-30 18:23:10 -07:00
|
|
|
}
|
|
|
|
|
2018-06-29 19:33:16 -07:00
|
|
|
impl Unpin for Waker {}
|
2018-05-30 18:23:10 -07:00
|
|
|
unsafe impl Send for Waker {}
|
|
|
|
unsafe impl Sync for Waker {}
|
|
|
|
|
|
|
|
impl Waker {
|
|
|
|
/// Wake up the task associated with this `Waker`.
|
|
|
|
pub fn wake(&self) {
|
2019-01-29 19:02:42 -08:00
|
|
|
// The actual wakeup call is delegated through a virtual function call
|
|
|
|
// to the implementation which is defined by the executor.
|
|
|
|
unsafe { (self.waker.vtable.wake)(self.waker.data) }
|
2018-05-30 18:23:10 -07:00
|
|
|
}
|
|
|
|
|
2019-01-29 19:02:42 -08:00
|
|
|
/// Returns whether or not this `Waker` and other `Waker` have awaken the same task.
|
2018-05-30 18:23:10 -07:00
|
|
|
///
|
|
|
|
/// 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
|
2019-01-29 19:02:42 -08:00
|
|
|
/// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
|
2018-05-30 18:23:10 -07:00
|
|
|
///
|
|
|
|
/// This function is primarily used for optimization purposes.
|
|
|
|
pub fn will_wake(&self, other: &Waker) -> bool {
|
2019-01-29 19:02:42 -08:00
|
|
|
self.waker == other.waker
|
2018-05-30 18:23:10 -07:00
|
|
|
}
|
2018-10-01 15:16:06 -07:00
|
|
|
|
2019-01-29 19:02:42 -08:00
|
|
|
/// Creates a new `Waker` from `RawWaker`.
|
2018-10-01 15:16:06 -07:00
|
|
|
///
|
2019-01-29 19:02:42 -08:00
|
|
|
/// The method cannot check whether `RawWaker` fulfills the required API
|
|
|
|
/// contract to make it usable for `Waker` and is therefore unsafe.
|
|
|
|
pub unsafe fn new_unchecked(waker: RawWaker) -> Waker {
|
|
|
|
Waker {
|
|
|
|
waker: waker,
|
|
|
|
}
|
2018-10-01 15:16:06 -07:00
|
|
|
}
|
2018-05-30 18:23:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for Waker {
|
|
|
|
fn clone(&self) -> Self {
|
2019-01-29 19:02:42 -08:00
|
|
|
Waker {
|
|
|
|
waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
|
2018-05-30 18:23:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for Waker {
|
|
|
|
fn drop(&mut self) {
|
2019-01-29 19:02:42 -08:00
|
|
|
unsafe { (self.waker.vtable.drop_fn)(self.waker.data) }
|
2018-05-30 18:23:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-29 19:02:42 -08:00
|
|
|
impl fmt::Debug for Waker {
|
2018-05-30 18:23:10 -07:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-01-29 19:02:42 -08:00
|
|
|
f.debug_struct("Waker")
|
2018-05-30 18:23:10 -07:00
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|