mirror of
https://github.com/transmission/transmission
synced 2025-02-22 22:20:39 +00:00
fix: assert failure when Transmission quit with pending IP queries (#5721)
This commit is contained in:
parent
56b27057fd
commit
449da2b53e
1 changed files with 28 additions and 18 deletions
|
@ -33,13 +33,6 @@ static_assert(TR_AF_INET6 == 1);
|
|||
|
||||
auto TR_CONSTEXPR23 protocol_str(tr_address_type type) noexcept
|
||||
{
|
||||
/* TODO: very slight performance nit
|
||||
* - If upgrading to C++20, change Map to a consteval lambda:
|
||||
* static auto Map = []() consteval { return std::array{ "IPv4"sv, "IPv6"sv }; };
|
||||
* - If upgrading to C++23, change Map to static constexpr
|
||||
*
|
||||
* Ref: https://wg21.link/p2647r1
|
||||
*/
|
||||
static auto TR_CONSTEXPR23 map = std::array{ "IPv4"sv, "IPv6"sv };
|
||||
return map[type];
|
||||
}
|
||||
|
@ -50,6 +43,10 @@ auto constexpr IPQueryServices = std::array{ std::array{ "https://ip4.transmissi
|
|||
auto constexpr UpkeepInterval = 30min;
|
||||
auto constexpr RetryUpkeepInterval = 30s;
|
||||
|
||||
// Normally there should only ever be 1 cache instance during the entire program execution
|
||||
// This is a counter only to cater for SessionTest.honorsSettings
|
||||
std::size_t cache_exists = 0;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace
|
||||
|
@ -147,6 +144,8 @@ tr_global_ip_cache::tr_global_ip_cache(Mediator& mediator_in)
|
|||
upkeep_timers_[i]->set_callback(cb);
|
||||
start_timer(type, UpkeepInterval);
|
||||
}
|
||||
|
||||
++cache_exists;
|
||||
}
|
||||
|
||||
std::unique_ptr<tr_global_ip_cache> tr_global_ip_cache::create(tr_global_ip_cache::Mediator& mediator_in)
|
||||
|
@ -161,10 +160,15 @@ tr_global_ip_cache::~tr_global_ip_cache()
|
|||
global_addr_mutex_[TR_AF_INET], global_addr_mutex_[TR_AF_INET6],
|
||||
source_addr_mutex_[TR_AF_INET], source_addr_mutex_[TR_AF_INET6] };
|
||||
|
||||
TR_ASSERT(std::all_of(
|
||||
if (std::all_of(
|
||||
std::begin(is_updating_),
|
||||
std::end(is_updating_),
|
||||
[](is_updating_t const& v) { return v == is_updating_t::ABORT; }));
|
||||
[](is_updating_t const& v) { return v == is_updating_t::ABORT; }))
|
||||
{
|
||||
tr_logAddDebug("Destructed while some global IP queries were pending.");
|
||||
}
|
||||
|
||||
--cache_exists;
|
||||
}
|
||||
|
||||
bool tr_global_ip_cache::try_shutdown() noexcept
|
||||
|
@ -238,7 +242,13 @@ void tr_global_ip_cache::update_global_addr(tr_address_type type) noexcept
|
|||
tr_web::FetchOptions::IPProtocol::V6 };
|
||||
auto options = tr_web::FetchOptions{ IPQueryServices[type][ix_service_[type]],
|
||||
[this, type](tr_web::FetchResponse const& response)
|
||||
{ this->on_response_ip_query(type, response); },
|
||||
{
|
||||
// Check to avoid segfault
|
||||
if (cache_exists != 0)
|
||||
{
|
||||
this->on_response_ip_query(type, response);
|
||||
}
|
||||
},
|
||||
nullptr };
|
||||
options.ip_proto = IPProtocolMap[type];
|
||||
options.sndbuf = 4096;
|
||||
|
@ -312,14 +322,14 @@ void tr_global_ip_cache::on_response_ip_query(tr_address_type type, tr_web::Fetc
|
|||
}
|
||||
|
||||
// Try next IP query URL
|
||||
if (!success && ++ix_service_[type] < std::size(IPQueryServices[type]))
|
||||
if (!success)
|
||||
{
|
||||
if (++ix_service_[type] < std::size(IPQueryServices[type]))
|
||||
{
|
||||
update_global_addr(type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
tr_logAddDebug(fmt::format("Couldn't obtain global {} address", protocol));
|
||||
unset_global_addr(type);
|
||||
upkeep_timers_[type]->set_interval(RetryUpkeepInterval);
|
||||
|
|
Loading…
Reference in a new issue