diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index ab8edd0bb..3f04baf17 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -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::create( TR_ASSERT(session != nullptr); auto lock = session->unique_lock(); - auto io = std::make_shared(session, std::move(socket), parent, info_hash, is_incoming, is_seed); + auto const io = std::shared_ptr{ + 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(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(); } // --- diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index dea6b12f6..f1bf1c145 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -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 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 const flush_outbuf_trigger_; + libtransmission::evhelpers::event_unique_ptr event_read_; libtransmission::evhelpers::event_unique_ptr event_write_;