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
72
73
74
75
76
77
78
79
80
81
82
83
//! # Task State
//! Where a spawned task is in its life
/// The lifecycle of one spawned task
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum TaskState {
/// No task in this slot
///
/// A `TaskHandle` never reports this. An empty slot reads as
/// `Failed` through a handle
Free = 0,
/// Waiting for the `Executor` to claim it
Pending = 1,
/// Claimed, and running right now
///
/// Also a socket task waiting on the network, which holds no
/// thread while it waits but hasn't finished its run
Running = 2,
/// The output is written and safe to read
Ready = 3,
/// The output was moved out by `take`,
/// so there is nothing left to hand out
Taken = 4,
/// Abandoned by a listener
///
/// A task already in flight still runs to the end,
/// its result just never reaches anyone
Cancelled = 5,
/// Nothing is going to produce an output for this task
///
/// The task panicked, the thread running it died, or nothing
/// was left to run it
Failed = 6,
/// A run went past the task's timeout
///
/// Like a cancel, a run already in flight may still finish, but
/// its result never reaches anyone
TimedOut = 7,
}
impl TaskState {
/// Rebuilds a state from the raw value in the atomic
///
/// Anything unrecognised reads as `Failed`
#[inline(always)]
pub(crate) fn from_u32(raw: u32) -> Self {
match raw {
0 => Self::Free,
1 => Self::Pending,
2 => Self::Running,
3 => Self::Ready,
4 => Self::Taken,
5 => Self::Cancelled,
7 => Self::TimedOut,
_ => Self::Failed,
}
}
/// Whether a read on this state returns without waiting
///
/// #### Note
/// Doesn't mean there is an output. A cancelled, failed or
/// taken task has settled with nothing to hand out
#[inline(always)]
pub fn terminal(self) -> bool {
!matches!(self, Self::Pending | Self::Running)
}
/// Whether the task was stopped before it could finish, by a
/// cancel or a timeout
#[inline(always)]
pub(crate) fn stopped(self) -> bool {
matches!(self, Self::Cancelled | Self::TimedOut)
}
}