From 5e4c7f9a1ec6e2f246b9de54bf42980eb3d76a9f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 10 Jul 2022 13:51:35 -0500 Subject: [PATCH] refactor: use std::deque for tr_peerIo.outbuf_info (#3428) --- libtransmission/peer-io.cc | 115 ++++++------------------------------- libtransmission/peer-io.h | 4 +- 2 files changed, 20 insertions(+), 99 deletions(-) diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 9a3290ecd..7312ac804 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -71,89 +71,22 @@ static size_t guessPacketOverhead(size_t d) return (unsigned int)(d * (100.0 / assumed_payload_data_rate) - d); } -/** -*** -**/ - -struct tr_datatype -{ - struct tr_datatype* next; - size_t length; - bool isPieceData; -}; - -static struct tr_datatype* datatype_pool = nullptr; - -static struct tr_datatype* datatype_new() -{ - tr_datatype* ret = nullptr; - - if (datatype_pool == nullptr) - { - ret = tr_new(struct tr_datatype, 1); - } - else - { - ret = datatype_pool; - datatype_pool = datatype_pool->next; - } - - *ret = {}; - return ret; -} - -static void datatype_free(struct tr_datatype* datatype) -{ - datatype->next = datatype_pool; - datatype_pool = datatype; -} - -static void peer_io_pull_datatype(tr_peerIo* io) -{ - auto* const tmp = io->outbuf_datatypes; - - if (tmp != nullptr) - { - io->outbuf_datatypes = tmp->next; - datatype_free(tmp); - } -} - -static void peer_io_push_datatype(tr_peerIo* io, struct tr_datatype* datatype) -{ - tr_datatype* tmp = io->outbuf_datatypes; - - if (tmp != nullptr) - { - while (tmp->next != nullptr) - { - tmp = tmp->next; - } - - tmp->next = datatype; - } - else - { - io->outbuf_datatypes = datatype; - } -} - /*** **** ***/ static void didWriteWrapper(tr_peerIo* io, unsigned int bytes_transferred) { - while (bytes_transferred != 0 && tr_isPeerIo(io) && io->outbuf_datatypes != nullptr) + while (bytes_transferred != 0 && tr_isPeerIo(io) && !std::empty(io->outbuf_info)) { - struct tr_datatype* next = io->outbuf_datatypes; + auto& [n_bytes_left, is_piece_data] = io->outbuf_info.front(); - unsigned int const payload = std::min(uint64_t{ next->length }, uint64_t{ bytes_transferred }); + unsigned int const payload = std::min(uint64_t{ n_bytes_left }, uint64_t{ bytes_transferred }); /* For uTP sockets, the overhead is computed in utp_on_overhead. */ unsigned int const overhead = io->socket.type == TR_PEER_SOCKET_TYPE_TCP ? guessPacketOverhead(payload) : 0; uint64_t const now = tr_time_msec(); - io->bandwidth().notifyBandwidthConsumed(TR_UP, payload, next->isPieceData, now); + io->bandwidth().notifyBandwidthConsumed(TR_UP, payload, is_piece_data, now); if (overhead > 0) { @@ -162,18 +95,19 @@ static void didWriteWrapper(tr_peerIo* io, unsigned int bytes_transferred) if (io->didWrite != nullptr) { - io->didWrite(io, payload, next->isPieceData, io->userData); + io->didWrite(io, payload, is_piece_data, io->userData); } - if (tr_isPeerIo(io)) + if (!tr_isPeerIo(io)) { - bytes_transferred -= payload; - next->length -= payload; + break; + } - if (next->length == 0) - { - peer_io_pull_datatype(io); - } + bytes_transferred -= payload; + n_bytes_left -= payload; + if (n_bytes_left == 0) + { + io->outbuf_info.pop_front(); } } } @@ -832,11 +766,6 @@ static void io_dtor(tr_peerIo* const io) event_disable(io, EV_READ | EV_WRITE); io_close_socket(io); - while (io->outbuf_datatypes != nullptr) - { - peer_io_pull_datatype(io); - } - io->magic_number = ~0; delete io; } @@ -1021,14 +950,6 @@ static inline void processBuffer( TR_ASSERT(size == 0); } -static void addDatatype(tr_peerIo* io, size_t byteCount, bool isPieceData) -{ - auto* const d = datatype_new(); - d->isPieceData = isPieceData; - d->length = byteCount; - peer_io_push_datatype(io, d); -} - static inline void maybeEncryptBuffer(tr_peerIo* io, struct evbuffer* buf, size_t offset, size_t size) { if (io->encryption_type == PEER_ENCRYPTION_RC4) @@ -1042,7 +963,7 @@ void tr_peerIoWriteBuf(tr_peerIo* io, struct evbuffer* buf, bool isPieceData) size_t const byteCount = evbuffer_get_length(buf); maybeEncryptBuffer(io, buf, 0, byteCount); evbuffer_add_buffer(io->outbuf.get(), buf); - addDatatype(io, byteCount, isPieceData); + io->outbuf_info.emplace_back(byteCount, isPieceData); } void tr_peerIoWriteBytes(tr_peerIo* io, void const* bytes, size_t byteCount, bool isPieceData) @@ -1063,7 +984,7 @@ void tr_peerIoWriteBytes(tr_peerIo* io, void const* bytes, size_t byteCount, boo evbuffer_commit_space(io->outbuf.get(), &iovec, 1); - addDatatype(io, byteCount, isPieceData); + io->outbuf_info.emplace_back(byteCount, isPieceData); } /*** @@ -1283,14 +1204,14 @@ int tr_peerIoFlushOutgoingProtocolMsgs(tr_peerIo* io) /* count up how many bytes are used by non-piece-data messages at the front of our outbound queue */ - for (struct tr_datatype const* it = io->outbuf_datatypes; it != nullptr; it = it->next) + for (auto const& [n_bytes, is_piece_data] : io->outbuf_info) { - if (it->isPieceData) + if (is_piece_data) { break; } - byteCount += it->length; + byteCount += n_bytes; } return tr_peerIoFlush(io, TR_UP, byteCount); diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index 64659a270..3b1f177b4 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -16,6 +16,7 @@ #include // size_t #include // uintX_t #include +#include #include #include #include @@ -34,7 +35,6 @@ class tr_peerIo; struct tr_bandwidth; struct struct_utp_context; -struct tr_datatype; /** * @addtogroup networked_io Networked IO @@ -204,7 +204,7 @@ public: tr_evbuffer_ptr const inbuf = tr_evbuffer_ptr{ evbuffer_new() }; tr_evbuffer_ptr const outbuf = tr_evbuffer_ptr{ evbuffer_new() }; - struct tr_datatype* outbuf_datatypes = nullptr; + std::deque> outbuf_info; struct event* event_read = nullptr; struct event* event_write = nullptr;