blob: 10638234fdbb810a0d28d43b8a6b3886231bb424 (
plain)
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
|
#include "shared/connection.hh"
namespace shared {
void connection::send_packet(packet&& packet) noexcept {
packet.header.sequence = this->seq_num;
shared::send_packet(packet, this->sock, this->info);
++this->seq_num;
std::lock_guard<std::mutex> guard{*this->lock};
this->sent.push_back(packet);
}
bool connection::should_discard_packet(const packet& packet) noexcept {
std::lock_guard<std::mutex> guard{*this->lock};
// ack case
if (packet.header.command[0] == '\0') {
this->sent.erase(std::remove_if(std::begin(this->sent),
std::end(this->sent),
[&](const auto& p) {
return p.header.sequence <=
packet.header.sequence;
}),
std::end(this->sent));
return true;
}
// Send an ack for the packet if it's not an ack itself
auto ack_pkt = shared::contents_to_packet({}, "\0\0\0");
ack_pkt.header.sequence = packet.header.sequence;
shared::send_packet(ack_pkt, this->sock, this->info);
if (packet.header.sequence != this->ack_num) {
return true;
}
++this->ack_num;
return false;
}
// Reliable transport reads our packets on a different thread and resends if
// necessary.
void connection::do_reliable_transport() noexcept {
while (!*this->should_thread_exit) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::lock_guard<std::mutex> guard{*this->lock};
for (const auto& packet : this->sent) {
shared::send_packet(packet, this->sock, this->info);
}
}
}
} // namespace shared
|