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)]
6pub 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)]
15pub struct Operation(usize);
16
17impl 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]
24 pub fn hook<T>(r: &mut T) -> Operation {
25 let val: usize = 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)]
35pub 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
49impl From<usize> for Selected {
50 #[inline]
51 fn from(val: usize) -> Selected {
52 match val {
53 0 => Selected::Waiting,
54 1 => Selected::Aborted,
55 2 => Selected::Disconnected,
56 oper: usize => Selected::Operation(Operation(oper)),
57 }
58 }
59}
60
61impl Into<usize> for Selected {
62 #[inline]
63 fn into(self) -> usize {
64 match self {
65 Selected::Waiting => 0,
66 Selected::Aborted => 1,
67 Selected::Disconnected => 2,
68 Selected::Operation(Operation(val: usize)) => val,
69 }
70 }
71}
72