xref: /drstd/src/std/sync/mpmc/select.rs (revision 9670759b785600bf6315e4173e46a602f16add7a)
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