std/sync/mpmc/
select.rs

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 = 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 => 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)) => val,
69        }
70    }
71}