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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use std::io;
use std::process::ExitStatus;
use tokio::task::JoinHandle;
use super::super::kill;
#[derive(Clone)]
pub struct SharedCommandSpawned<T, R> {
data: T,
killer: kill::CommandKiller<R>,
}
pub(super) type CommandTokioJoinHandle<T> = JoinHandle<(
io::Result<ExitStatus>,
Option<kill::KillJoinHandleFinalStatus<T>>,
)>;
pub struct CommandJoinHandle<R>(CommandTokioJoinHandle<R>);
impl<R> CommandJoinHandle<R> {
pub async fn join(self) -> super::CommandStopped<(), R> {
let (exit_status, killed) = self.0.await.expect("command task handle should not panic");
super::CommandStopped {
data: (),
exit_status,
killed,
}
}
}
pub struct CommandSpawned<T, R> {
pub data: T,
pub killer: kill::CommandKiller<R>,
pub join_handle: CommandJoinHandle<R>,
}
impl<T, R> CommandSpawned<T, R> {
pub(super) fn new(
data: T,
kill_sender: kill::KillSender<R>,
join_handle: CommandTokioJoinHandle<R>,
) -> Self {
Self {
data,
killer: kill::CommandKiller::new(kill_sender),
join_handle: CommandJoinHandle(join_handle),
}
}
pub fn kill(&self, reason: kill::KillCommandReason<R>) -> kill::KillResult {
self.killer.kill(reason)
}
pub async fn wait_into_stopped(self) -> super::CommandStopped<T, R> {
let Self {
data, join_handle, ..
} = self;
join_handle.join().await.with_data(data).1
}
pub fn with_data<S>(self, new_data: S) -> (T, CommandSpawned<S, R>) {
let Self {
data,
join_handle,
killer,
} = self;
(
data,
CommandSpawned {
data: new_data,
join_handle,
killer,
},
)
}
}
impl<T: Clone, R> CommandSpawned<T, R> {
pub fn share_data(&self) -> T {
self.data.clone()
}
}
impl<T, R: Clone> CommandSpawned<T, R> {
pub fn share_killer(&self) -> kill::CommandKiller<R> {
self.killer.clone()
}
}
impl<T: Clone, R: Clone> CommandSpawned<T, R> {
pub fn share(&self) -> SharedCommandSpawned<T, R> {
SharedCommandSpawned {
data: self.data.clone(),
killer: self.killer.clone(),
}
}
}