| /// Temporary data that gets initialized during a blocking operation, and is consumed by | |
| /// `read` or `write`. | |
| /// | |
| /// Each field contains data associated with a specific channel flavor. | |
| #[derive(Debug, Default)] | |
| pub struct Token { | |
| pub(crate) array: super::array::ArrayToken, | |
| pub(crate) list: super::list::ListToken, | |
| #[allow(dead_code)] | |
| pub(crate) zero: super::zero::ZeroToken, | |
| } | |
| /// Identifier associated with an operation by a specific thread on a specific channel. | |
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | |
| pub struct Operation(usize); | |
| impl Operation { | |
| /// Creates an operation identifier from a mutable reference. | |
| /// | |
| /// This function essentially just turns the address of the reference into a number. The | |
| /// reference should point to a variable that is specific to the thread and the operation, | |
| /// and is alive for the entire duration of a blocking operation. | |
| #[inline] | |
| pub fn hook<T>(r: &mut T) -> Operation { | |
| let val = r as *mut T as usize; | |
| // Make sure that the pointer address doesn't equal the numerical representation of | |
| // `Selected::{Waiting, Aborted, Disconnected}`. | |
| assert!(val > 2); | |
| Operation(val) | |
| } | |
| } | |
| /// Current state of a blocking operation. | |
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | |
| pub enum Selected { | |
| /// Still waiting for an operation. | |
| Waiting, | |
| /// The attempt to block the current thread has been aborted. | |
| Aborted, | |
| /// An operation became ready because a channel is disconnected. | |
| Disconnected, | |
| /// An operation became ready because a message can be sent or received. | |
| Operation(Operation), | |
| } | |
| impl From<usize> for Selected { | |
| #[inline] | |
| fn from(val: usize) -> Selected { | |
| match val { | |
| 0 => Selected::Waiting, | |
| 1 => Selected::Aborted, | |
| 2 => Selected::Disconnected, | |
| oper => Selected::Operation(Operation(oper)), | |
| } | |
| } | |
| } | |
| impl Into<usize> for Selected { | |
| #[inline] | |
| fn into(self) -> usize { | |
| match self { | |
| Selected::Waiting => 0, | |
| Selected::Aborted => 1, | |
| Selected::Disconnected => 2, | |
| Selected::Operation(Operation(val)) => val, | |
| } | |
| } | |
| } |