mirror of
https://github.com/transmission/transmission.git
synced 2026-02-14 23:19:34 +00:00
perf: use timer to flush outbuf to avoid taking lock frequently (#8454)
* perf: use timer to flush outbuf to avoid taking lock frequently
* code review: extract to `flush_outbuf_soon()`
* code review: make `flush_outbuf_trigger_` const
(cherry picked from commit 4d695a8a4c)
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include "libtransmission/peer-io.h"
|
||||
#include "libtransmission/peer-socket.h" // tr_peer_socket, tr_netOpen...
|
||||
#include "libtransmission/session.h"
|
||||
#include "libtransmission/timer.h"
|
||||
#include "libtransmission/tr-assert.h"
|
||||
#include "libtransmission/utils.h" // for _()
|
||||
|
||||
@@ -82,6 +83,7 @@ tr_peerIo::tr_peerIo(
|
||||
: bandwidth_{ parent_bandwidth }
|
||||
, info_hash_{ info_hash != nullptr ? *info_hash : tr_sha1_digest_t{} }
|
||||
, session_{ session }
|
||||
, flush_outbuf_trigger_{ session->timerMaker().create() }
|
||||
, client_is_seed_{ client_is_seed }
|
||||
, is_incoming_{ is_incoming }
|
||||
{
|
||||
@@ -99,8 +101,18 @@ std::shared_ptr<tr_peerIo> tr_peerIo::create(
|
||||
TR_ASSERT(session != nullptr);
|
||||
auto lock = session->unique_lock();
|
||||
|
||||
auto io = std::make_shared<tr_peerIo>(session, std::move(socket), parent, info_hash, is_incoming, is_seed);
|
||||
auto const io = std::shared_ptr<tr_peerIo>{
|
||||
new tr_peerIo{ session, std::move(socket), parent, info_hash, is_incoming, is_seed }
|
||||
};
|
||||
io->bandwidth().set_peer(io);
|
||||
io->flush_outbuf_trigger_->set_callback(
|
||||
[weak = io->weak_from_this()]
|
||||
{
|
||||
if (auto const ptr = weak.lock())
|
||||
{
|
||||
ptr->try_write(SIZE_MAX);
|
||||
}
|
||||
});
|
||||
tr_logAddTraceIo(io, fmt::format("bandwidth is {}; its parent is {}", fmt::ptr(&io->bandwidth()), fmt::ptr(parent)));
|
||||
return io;
|
||||
}
|
||||
@@ -567,6 +579,11 @@ size_t tr_peerIo::flush_outgoing_protocol_msgs()
|
||||
return flush(TR_UP, byte_count);
|
||||
}
|
||||
|
||||
void tr_peerIo::flush_outbuf_soon()
|
||||
{
|
||||
flush_outbuf_trigger_->start_single_shot(std::chrono::milliseconds::zero());
|
||||
}
|
||||
|
||||
void tr_peerIo::write_bytes(void const* bytes, size_t n_bytes, bool is_piece_data)
|
||||
{
|
||||
if (n_bytes == 0U)
|
||||
@@ -580,14 +597,7 @@ void tr_peerIo::write_bytes(void const* bytes, size_t n_bytes, bool is_piece_dat
|
||||
filter_.encrypt(reinterpret_cast<std::byte const*>(bytes), n_bytes, resbuf);
|
||||
outbuf_.commit_space(n_bytes);
|
||||
|
||||
session_->queue_session_thread(
|
||||
[ptr = weak_from_this()]()
|
||||
{
|
||||
if (auto io = ptr.lock(); io)
|
||||
{
|
||||
io->try_write(SIZE_MAX);
|
||||
}
|
||||
});
|
||||
flush_outbuf_soon();
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
@@ -34,10 +34,15 @@ struct tr_error;
|
||||
struct tr_session;
|
||||
struct tr_socket_address;
|
||||
|
||||
namespace libtransmission::test
|
||||
namespace libtransmission
|
||||
{
|
||||
class Timer;
|
||||
|
||||
namespace test
|
||||
{
|
||||
class HandshakeTest;
|
||||
} // namespace libtransmission::test
|
||||
}
|
||||
} // namespace libtransmission
|
||||
|
||||
enum class ReadState : uint8_t
|
||||
{
|
||||
@@ -63,14 +68,6 @@ class tr_peerIo final : public std::enable_shared_from_this<tr_peerIo>
|
||||
using GotError = void (*)(tr_peerIo* io, tr_error const& error, void* user_data);
|
||||
|
||||
public:
|
||||
tr_peerIo(
|
||||
tr_session* session,
|
||||
tr_peer_socket&& socket,
|
||||
tr_bandwidth* parent_bandwidth,
|
||||
tr_sha1_digest_t const* info_hash,
|
||||
bool is_incoming,
|
||||
bool client_is_seed);
|
||||
|
||||
~tr_peerIo();
|
||||
|
||||
tr_peerIo(tr_peerIo const&) = delete;
|
||||
@@ -322,6 +319,14 @@ private:
|
||||
|
||||
friend class libtransmission::test::HandshakeTest;
|
||||
|
||||
tr_peerIo(
|
||||
tr_session* session,
|
||||
tr_peer_socket&& socket,
|
||||
tr_bandwidth* parent_bandwidth,
|
||||
tr_sha1_digest_t const* info_hash,
|
||||
bool is_incoming,
|
||||
bool client_is_seed);
|
||||
|
||||
[[nodiscard]] constexpr auto client_is_seed() const noexcept
|
||||
{
|
||||
return client_is_seed_;
|
||||
@@ -342,6 +347,8 @@ private:
|
||||
|
||||
void close();
|
||||
|
||||
void flush_outbuf_soon();
|
||||
|
||||
static void event_read_cb(evutil_socket_t fd, short /*event*/, void* vio);
|
||||
static void event_write_cb(evutil_socket_t fd, short /*event*/, void* vio);
|
||||
|
||||
@@ -385,6 +392,8 @@ private:
|
||||
GotError got_error_ = nullptr;
|
||||
void* user_data_ = nullptr;
|
||||
|
||||
std::unique_ptr<libtransmission::Timer> const flush_outbuf_trigger_;
|
||||
|
||||
libtransmission::evhelpers::event_unique_ptr event_read_;
|
||||
libtransmission::evhelpers::event_unique_ptr event_write_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user