1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-02-22 06:00:41 +00:00

refactor: use std::deque for tr_peerIo.outbuf_info (#3428)

This commit is contained in:
Charles Kerr 2022-07-10 13:51:35 -05:00 committed by GitHub
parent 58c8de9fd3
commit 5e4c7f9a1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 99 deletions

View file

@ -71,89 +71,22 @@ static size_t guessPacketOverhead(size_t d)
return (unsigned int)(d * (100.0 / assumed_payload_data_rate) - 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) 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. */ /* 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; unsigned int const overhead = io->socket.type == TR_PEER_SOCKET_TYPE_TCP ? guessPacketOverhead(payload) : 0;
uint64_t const now = tr_time_msec(); 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) if (overhead > 0)
{ {
@ -162,18 +95,19 @@ static void didWriteWrapper(tr_peerIo* io, unsigned int bytes_transferred)
if (io->didWrite != nullptr) 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; break;
next->length -= payload; }
if (next->length == 0) bytes_transferred -= payload;
{ n_bytes_left -= payload;
peer_io_pull_datatype(io); 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); event_disable(io, EV_READ | EV_WRITE);
io_close_socket(io); io_close_socket(io);
while (io->outbuf_datatypes != nullptr)
{
peer_io_pull_datatype(io);
}
io->magic_number = ~0; io->magic_number = ~0;
delete io; delete io;
} }
@ -1021,14 +950,6 @@ static inline void processBuffer(
TR_ASSERT(size == 0); 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) static inline void maybeEncryptBuffer(tr_peerIo* io, struct evbuffer* buf, size_t offset, size_t size)
{ {
if (io->encryption_type == PEER_ENCRYPTION_RC4) 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); size_t const byteCount = evbuffer_get_length(buf);
maybeEncryptBuffer(io, buf, 0, byteCount); maybeEncryptBuffer(io, buf, 0, byteCount);
evbuffer_add_buffer(io->outbuf.get(), buf); 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) 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); 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 /* count up how many bytes are used by non-piece-data messages
at the front of our outbound queue */ 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; break;
} }
byteCount += it->length; byteCount += n_bytes;
} }
return tr_peerIoFlush(io, TR_UP, byteCount); return tr_peerIoFlush(io, TR_UP, byteCount);

View file

@ -16,6 +16,7 @@
#include <cstddef> // size_t #include <cstddef> // size_t
#include <cstdint> // uintX_t #include <cstdint> // uintX_t
#include <ctime> #include <ctime>
#include <deque>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
@ -34,7 +35,6 @@
class tr_peerIo; class tr_peerIo;
struct tr_bandwidth; struct tr_bandwidth;
struct struct_utp_context; struct struct_utp_context;
struct tr_datatype;
/** /**
* @addtogroup networked_io Networked IO * @addtogroup networked_io Networked IO
@ -204,7 +204,7 @@ public:
tr_evbuffer_ptr const inbuf = tr_evbuffer_ptr{ evbuffer_new() }; tr_evbuffer_ptr const inbuf = tr_evbuffer_ptr{ evbuffer_new() };
tr_evbuffer_ptr const outbuf = tr_evbuffer_ptr{ evbuffer_new() }; tr_evbuffer_ptr const outbuf = tr_evbuffer_ptr{ evbuffer_new() };
struct tr_datatype* outbuf_datatypes = nullptr; std::deque<std::pair<size_t /*n_bytes*/, bool /*is_piece_data*/>> outbuf_info;
struct event* event_read = nullptr; struct event* event_read = nullptr;
struct event* event_write = nullptr; struct event* event_write = nullptr;