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
101
102
103
104
105
106
107
108
109
use ipmb::label;
use std::{
env,
process::Command,
sync::mpsc::{self, RecvTimeoutError},
thread,
time::Duration,
};
fn main() {
let mut args = env::args();
let command = args.next().unwrap();
match args.next() {
None => {
let (tx, mut rx) = ipmb::join::<ipmb::BytesMessage, ipmb::BytesMessage>(
ipmb::Options::new("reliability", label!("0"), ""),
None,
)
.unwrap();
let mut wait_list = vec![];
let mut kill_list = vec![];
for i in 1..4 {
let child = Command::new(command.clone())
.arg(i.to_string())
.spawn()
.unwrap();
match i {
2 | 3 => {
wait_list.push(child);
}
_ => {
kill_list.push(child);
}
}
}
thread::spawn(move || while rx.recv(None).is_ok() {});
for _ in 0..10_000 {
tx.send(ipmb::Message::new(
ipmb::Selector::multicast(ipmb::LabelOp::True),
ipmb::BytesMessage {
format: 0,
data: vec![0x00, 0x01, 0x02, 0x03],
},
))
.unwrap();
}
let (guard_tx, guard_rx) = mpsc::channel();
thread::spawn(move || {
for mut child in wait_list {
child.wait().unwrap();
}
guard_tx.send(()).unwrap();
});
match guard_rx.recv_timeout(Duration::from_secs(5)) {
Err(RecvTimeoutError::Timeout) => {
for mut child in kill_list {
child.kill().unwrap();
}
panic!("Timeout");
}
_ => {
for mut child in kill_list {
child.kill().unwrap();
}
}
}
}
Some(i) => {
let (tx, mut rx) = ipmb::join::<ipmb::BytesMessage, ipmb::BytesMessage>(
ipmb::Options::new("reliability", label!(i.to_string()), ""),
None,
)
.unwrap();
match i.as_str() {
"1" => {
drop(tx);
while rx.recv(None).is_ok() {}
}
"2" => {
drop(rx);
for _ in 0..10_000 {
tx.send(ipmb::Message::new(
ipmb::Selector::multicast(ipmb::LabelOp::True),
ipmb::BytesMessage {
format: 0,
data: vec![0x00, 0x01, 0x02, 0x03],
},
))
.unwrap();
}
}
_ => {
drop(tx);
drop(rx);
}
}
}
}
}