diff --git a/libtransmission/peer-mgr.cc b/libtransmission/peer-mgr.cc index 7e17a13cc..c132c4321 100644 --- a/libtransmission/peer-mgr.cc +++ b/libtransmission/peer-mgr.cc @@ -2422,8 +2422,6 @@ struct ComparePeerByActivity void closeBadPeers(tr_swarm* s, time_t const now_sec) { - auto const lock = s->unique_lock(); - for (auto* peer : getPeersToClose(s, now_sec)) { closePeer(peer); @@ -2433,9 +2431,8 @@ void closeBadPeers(tr_swarm* s, time_t const now_sec) void enforceTorrentPeerLimit(tr_swarm* swarm) { // do we have too many peers? - auto const n = swarm->peerCount(); auto const max = swarm->tor->peerLimit(); - if (n <= max) + if (auto const n = swarm->peerCount(); n <= max) { return; } @@ -2480,6 +2477,7 @@ void tr_peerMgr::reconnectPulse() { using namespace disconnect_helpers; + auto const lock = session->unique_lock(); auto const now_sec = tr_time(); // remove crappy peers diff --git a/libtransmission/tr-buffer.h b/libtransmission/tr-buffer.h index 5e158ae32..e0732bcfc 100644 --- a/libtransmission/tr-buffer.h +++ b/libtransmission/tr-buffer.h @@ -44,79 +44,96 @@ public: [[nodiscard]] value_type& operator*() noexcept { - return *reinterpret_cast(iov_.iov_base); + return reinterpret_cast(iov_.iov_base)[iov_offset_]; } [[nodiscard]] value_type operator*() const noexcept { - return *reinterpret_cast(iov_.iov_base); + return reinterpret_cast(iov_.iov_base)[iov_offset_]; } - [[nodiscard]] Iterator operator+(int n_bytes) + [[nodiscard]] Iterator operator+(size_t n_bytes) { - return Iterator(buf_, offset_ + n_bytes); + return Iterator{ buf_, offset() + n_bytes }; } - [[nodiscard]] Iterator operator-(int n_bytes) + [[nodiscard]] Iterator operator-(size_t n_bytes) { - return Iterator(buf_, offset_ - n_bytes); + return Iterator{ buf_, offset() - n_bytes }; } [[nodiscard]] constexpr auto operator-(Iterator const& that) const noexcept { - return offset_ - that.offset_; + return offset() - that.offset(); } Iterator& operator++() noexcept { - if (iov_.iov_len > 1) - { - iov_.iov_base = reinterpret_cast(iov_.iov_base) + 1; - --iov_.iov_len; - ++offset_; - } - else - { - setOffset(offset_ + 1); - } + *this += 1U; return *this; } - Iterator& operator+=(int n_bytes) + Iterator& operator+=(size_t n_bytes) { - setOffset(offset_ + n_bytes); + if (iov_offset_ + n_bytes < iov_.iov_len) + { + iov_offset_ += n_bytes; + } + else + { + incOffset(n_bytes); + } + return *this; } Iterator& operator--() noexcept { - // TODO(ckerr) inefficient; calls evbuffer_ptr_peek() every time - setOffset(offset_ - 1); + if (iov_offset_ > 0) + { + --iov_offset_; + } + else + { + setOffset(offset() - 1); + } return *this; } [[nodiscard]] constexpr bool operator==(Iterator const& that) const noexcept { - return offset_ == that.offset_; + return offset() == that.offset(); } [[nodiscard]] constexpr bool operator!=(Iterator const& that) const noexcept { - return !(*this == that); + return offset() != that.offset(); } private: + [[nodiscard]] constexpr size_t offset() const noexcept + { + return ptr_.pos + iov_offset_; + } + + void incOffset(size_t increment) + { + evbuffer_ptr_set(buf_, &ptr_, iov_offset_ + increment, EVBUFFER_PTR_ADD); + evbuffer_peek(buf_, std::numeric_limits::max(), &ptr_, &iov_, 1); + iov_offset_ = 0; + } + void setOffset(size_t offset) { - offset_ = offset; - auto ptr = evbuffer_ptr{}; - evbuffer_ptr_set(buf_, &ptr, offset, EVBUFFER_PTR_SET); - evbuffer_peek(buf_, std::numeric_limits::max(), &ptr, &iov_, 1); + evbuffer_ptr_set(buf_, &ptr_, offset, EVBUFFER_PTR_SET); + evbuffer_peek(buf_, std::numeric_limits::max(), &ptr_, &iov_, 1); + iov_offset_ = 0; } evbuffer* buf_; + evbuffer_ptr ptr_ = {}; Iovec iov_ = {}; - size_t offset_ = 0; + size_t iov_offset_ = 0; }; Buffer() = default; @@ -351,11 +368,8 @@ public: [[nodiscard]] std::string toString() const { auto str = std::string{}; - str.reserve(size()); - for (auto const& by : *this) - { - str.push_back(*reinterpret_cast(&by)); - } + str.resize(size()); + evbuffer_copyout(buf_.get(), std::data(str), std::size(str)); return str; }