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:
parent
58c8de9fd3
commit
5e4c7f9a1e
2 changed files with 20 additions and 99 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue