1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/// 在阻塞操作期间初始化并由 `read` 或 `write` 使用的临时数据。
///
///
/// 每个字段都包含与特定通道风味关联的数据。
#[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,
}

/// 与特定线程在特定通道上的操作关联的标识符。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Operation(usize);

impl Operation {
    /// 从可变引用创建操作标识符。
    ///
    /// 这个函数本质上只是把引用的地址变成了一个数字。
    /// 引用应该指向特定于线程和操作的变量,并且在阻塞操作的整个持续时间内都是有效的。
    ///
    #[inline]
    pub fn hook<T>(r: &mut T) -> Operation {
        let val = r as *mut T as usize;
        // 确保指针地址不等于 `Selected::{Waiting, Aborted, Disconnected}` 的数值表示。
        //
        assert!(val > 2);
        Operation(val)
    }
}

/// 阻塞操作的当前状态。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Selected {
    /// 还在等操作。
    Waiting,

    /// 阻止当前线程的尝试已中止。
    Aborted,

    /// 操作已准备就绪,因为通道已断开连接。
    Disconnected,

    /// 操作准备就绪,因为可以发送或接收消息。
    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,
        }
    }
}