Codechange: use std::deque of std::unique_ptr to queue packets

This commit is contained in:
Rubidium
2024-02-03 19:35:36 +01:00
committed by rubidium42
parent c77a45ed86
commit 36e1b32ccf
5 changed files with 32 additions and 99 deletions

View File

@@ -28,7 +28,7 @@
* loose some the data of the packet, so there you pass the maximum
* size for the packet you expect from the network.
*/
Packet::Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size) : next(nullptr), pos(0), limit(limit)
Packet::Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size) : pos(0), limit(limit)
{
assert(cs != nullptr);
@@ -44,45 +44,20 @@ Packet::Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size)
* the limit as it might break things if the other side is not expecting
* much larger packets than what they support.
*/
Packet::Packet(PacketType type, size_t limit) : next(nullptr), pos(0), limit(limit), cs(nullptr)
Packet::Packet(PacketType type, size_t limit) : pos(0), limit(limit), cs(nullptr)
{
/* Allocate space for the the size so we can write that in just before sending the packet. */
this->Send_uint16(0);
this->Send_uint8(type);
}
/**
* Add the given Packet to the end of the queue of packets.
* @param queue The pointer to the begin of the queue.
* @param packet The packet to append to the queue.
*/
/* static */ void Packet::AddToQueue(Packet **queue, Packet *packet)
{
while (*queue != nullptr) queue = &(*queue)->next;
*queue = packet;
}
/**
* Pop the packet from the begin of the queue and set the
* begin of the queue to the second element in the queue.
* @param queue The pointer to the begin of the queue.
* @return The Packet that used to be a the begin of the queue.
*/
/* static */ Packet *Packet::PopFromQueue(Packet **queue)
{
Packet *p = *queue;
*queue = p->next;
p->next = nullptr;
return p;
}
/**
* Writes the packet size from the raw packet from packet->size
*/
void Packet::PrepareToSend()
{
assert(this->cs == nullptr && this->next == nullptr);
assert(this->cs == nullptr);
this->buffer[0] = GB(this->Size(), 0, 8);
this->buffer[1] = GB(this->Size(), 8, 8);
@@ -268,7 +243,7 @@ size_t Packet::Size() const
*/
bool Packet::ParsePacketSize()
{
assert(this->cs != nullptr && this->next == nullptr);
assert(this->cs != nullptr);
size_t size = (size_t)this->buffer[0];
size += (size_t)this->buffer[1] << 8;

View File

@@ -41,8 +41,6 @@ typedef uint8_t PacketType; ///< Identifier for the packet
*/
struct Packet {
private:
/** The next packet. Used for queueing packets before sending. */
Packet *next;
/** The current read/write position in the packet */
PacketSize pos;
/** The buffer of this packet. */
@@ -57,9 +55,6 @@ public:
Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = sizeof(PacketSize));
Packet(PacketType type, size_t limit = COMPAT_MTU);
static void AddToQueue(Packet **queue, Packet *packet);
static Packet *PopFromQueue(Packet **queue);
/* Sending/writing of packets */
void PrepareToSend();

View File

@@ -22,28 +22,15 @@
*/
NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) :
NetworkSocketHandler(),
packet_queue(nullptr), packet_recv(nullptr),
sock(s), writable(false)
{
}
NetworkTCPSocketHandler::~NetworkTCPSocketHandler()
{
this->EmptyPacketQueue();
this->CloseSocket();
}
/**
* Free all pending and partially received packets.
*/
void NetworkTCPSocketHandler::EmptyPacketQueue()
{
while (this->packet_queue != nullptr) {
delete Packet::PopFromQueue(&this->packet_queue);
}
this->packet_recv = nullptr;
}
/**
* Close the actual socket of the connection.
* Please make sure CloseConnection is called before CloseSocket, as
@@ -66,7 +53,8 @@ NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection([[maybe_unused]] bool
this->MarkClosed();
this->writable = false;
this->EmptyPacketQueue();
this->packet_queue.clear();
this->packet_recv = nullptr;
return NETWORK_RECV_STATUS_OKAY;
}
@@ -82,7 +70,7 @@ void NetworkTCPSocketHandler::SendPacket(Packet *packet)
assert(packet != nullptr);
packet->PrepareToSend();
Packet::AddToQueue(&this->packet_queue, packet);
this->packet_queue.push_back(std::unique_ptr<Packet>(packet));
}
/**
@@ -97,15 +85,13 @@ void NetworkTCPSocketHandler::SendPacket(Packet *packet)
*/
SendPacketsState NetworkTCPSocketHandler::SendPackets(bool closing_down)
{
ssize_t res;
Packet *p;
/* We can not write to this socket!! */
if (!this->writable) return SPS_NONE_SENT;
if (!this->IsConnected()) return SPS_CLOSED;
while ((p = this->packet_queue) != nullptr) {
res = p->TransferOut<int>(send, this->sock, 0);
while (!this->packet_queue.empty()) {
Packet *p = this->packet_queue.front().get();
ssize_t res = p->TransferOut<int>(send, this->sock, 0);
if (res == -1) {
NetworkError err = NetworkError::GetLast();
if (!err.WouldBlock()) {
@@ -127,7 +113,7 @@ SendPacketsState NetworkTCPSocketHandler::SendPackets(bool closing_down)
/* Is this packet sent? */
if (p->RemainingBytesToTransfer() == 0) {
/* Go to the next packet */
delete Packet::PopFromQueue(&this->packet_queue);
this->packet_queue.pop_front();
} else {
return SPS_PARTLY_SENT;
}

View File

@@ -30,7 +30,7 @@ enum SendPacketsState {
/** Base socket handler for all TCP sockets */
class NetworkTCPSocketHandler : public NetworkSocketHandler {
private:
Packet *packet_queue; ///< Packets that are awaiting delivery
std::deque<std::unique_ptr<Packet>> packet_queue; ///< Packets that are awaiting delivery. Cannot be std::queue as that does not have a clear() function.
std::unique_ptr<Packet> packet_recv; ///< Partially received packet
void EmptyPacketQueue();
@@ -58,7 +58,7 @@ public:
* Whether there is something pending in the send queue.
* @return true when something is pending in the send queue.
*/
bool HasSendQueue() { return this->packet_queue != nullptr; }
bool HasSendQueue() { return !this->packet_queue.empty(); }
NetworkTCPSocketHandler(SOCKET s = INVALID_SOCKET);
~NetworkTCPSocketHandler();