1 /// Temporary data that gets initialized during a blocking operation, and is consumed by 2 /// `read` or `write`. 3 /// 4 /// Each field contains data associated with a specific channel flavor. 5 #[derive(Debug, Default)] 6 pub struct Token { 7 pub(crate) array: super::array::ArrayToken, 8 pub(crate) list: super::list::ListToken, 9 #[allow(dead_code)] 10 pub(crate) zero: super::zero::ZeroToken, 11 } 12 13 /// Identifier associated with an operation by a specific thread on a specific channel. 14 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 15 pub struct Operation(usize); 16 17 impl Operation { 18 /// Creates an operation identifier from a mutable reference. 19 /// 20 /// This function essentially just turns the address of the reference into a number. The 21 /// reference should point to a variable that is specific to the thread and the operation, 22 /// and is alive for the entire duration of a blocking operation. 23 #[inline] hook<T>(r: &mut T) -> Operation24 pub fn hook<T>(r: &mut T) -> Operation { 25 let val = r as *mut T as usize; 26 // Make sure that the pointer address doesn't equal the numerical representation of 27 // `Selected::{Waiting, Aborted, Disconnected}`. 28 assert!(val > 2); 29 Operation(val) 30 } 31 } 32 33 /// Current state of a blocking operation. 34 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 35 pub enum Selected { 36 /// Still waiting for an operation. 37 Waiting, 38 39 /// The attempt to block the current thread has been aborted. 40 Aborted, 41 42 /// An operation became ready because a channel is disconnected. 43 Disconnected, 44 45 /// An operation became ready because a message can be sent or received. 46 Operation(Operation), 47 } 48 49 impl From<usize> for Selected { 50 #[inline] from(val: usize) -> Selected51 fn from(val: usize) -> Selected { 52 match val { 53 0 => Selected::Waiting, 54 1 => Selected::Aborted, 55 2 => Selected::Disconnected, 56 oper => Selected::Operation(Operation(oper)), 57 } 58 } 59 } 60 61 impl Into<usize> for Selected { 62 #[inline] into(self) -> usize63 fn into(self) -> usize { 64 match self { 65 Selected::Waiting => 0, 66 Selected::Aborted => 1, 67 Selected::Disconnected => 2, 68 Selected::Operation(Operation(val)) => val, 69 } 70 } 71 } 72