diff --git a/libtransmission/announcer-common.h b/libtransmission/announcer-common.h index d59ff055d..94e7d6adc 100644 --- a/libtransmission/announcer-common.h +++ b/libtransmission/announcer-common.h @@ -147,29 +147,21 @@ struct tr_announce_response * https://www.bittorrent.org/beps/bep_0024.html */ std::optional external_ip; - static constexpr struct + static constexpr int compare_failed(tr_announce_response const& lhs, tr_announce_response const& rhs) noexcept { - static constexpr int compare(tr_announce_response const& lhs, tr_announce_response const& rhs) + if (auto val = tr_compare_3way(lhs.did_connect, rhs.did_connect); val != 0) { - if (auto val = tr_compare_3way(lhs.did_connect, rhs.did_connect); val != 0) - { - return val; - } - - if (auto val = tr_compare_3way(lhs.did_timeout, rhs.did_timeout); val != 0) - { - return -val; - } - - // Non-empty error message most likely means we reached the tracker - return -tr_compare_3way(std::empty(lhs.errmsg), std::empty(rhs.errmsg)); + return val; } - constexpr bool operator()(tr_announce_response const& lhs, tr_announce_response const& rhs) const noexcept + if (auto val = tr_compare_3way(lhs.did_timeout, rhs.did_timeout); val != 0) { - return compare(lhs, rhs) > 0; + return -val; } - } CompareFailed{}; + + // Non-empty error message most likely means we reached the tracker + return -tr_compare_3way(std::empty(lhs.errmsg), std::empty(rhs.errmsg)); + } }; // --- SCRAPE diff --git a/libtransmission/announcer-http.cc b/libtransmission/announcer-http.cc index 2d9488ed2..3d76902d7 100644 --- a/libtransmission/announcer-http.cc +++ b/libtransmission/announcer-http.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -92,11 +91,10 @@ struct http_announce_data , on_response{ std::move(on_response_in) } , log_name{ log_name_in } { - failed_responses.reserve(NUM_TR_AF_INET_TYPES); } tr_sha1_digest_t info_hash = {}; - std::vector failed_responses; + std::optional failed_response; tr_announce_response_func on_response; @@ -162,16 +160,14 @@ void onAnnounceDone(tr_web::FetchResponse const& web_response) } else { - data->failed_responses.emplace_back(std::move(response)); + if (!data->failed_response || tr_announce_response::compare_failed(*data->failed_response, response) < 0) + { + data->failed_response = std::move(response); + } + if (got_all_responses) { - auto const begin = std::begin(data->failed_responses); - std::partial_sort( - begin, - std::next(begin), - std::end(data->failed_responses), - tr_announce_response::CompareFailed); - data->on_response(data->failed_responses.front()); + data->on_response(*data->failed_response); } } } diff --git a/libtransmission/announcer-udp.cc b/libtransmission/announcer-udp.cc index 76af1aac8..61ef7b570 100644 --- a/libtransmission/announcer-udp.cc +++ b/libtransmission/announcer-udp.cc @@ -201,13 +201,14 @@ public: } else if (!succeeded_) { - failed_responses_.emplace_back(std::move(response)); + if (!failed_responses_ || tr_announce_response::compare_failed(*failed_responses_, response) < 0) + { + failed_responses_ = std::move(response); + } if (got_all_responses) { - auto const begin = std::begin(failed_responses_); - std::partial_sort(begin, std::next(begin), std::end(failed_responses_), tr_announce_response::CompareFailed); - on_response_(failed_responses_.front()); + on_response_(*failed_responses_); } } } @@ -215,7 +216,7 @@ public: private: bool succeeded_ = false; - std::vector failed_responses_; + std::optional failed_responses_; tr_announce_response_func on_response_;