From 6c9c40fd7ca409b39989a3d3a2b205df544d1db0 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Wed, 9 Nov 2022 08:02:34 +0300 Subject: [PATCH] Avoid blocking call when changing libtorrent session settings We don't really need to get currently used settings pack in order to apply changes to session settings. It is enough to apply settings pack that contains only updated settings. PR #17989. --- src/base/bittorrent/portforwarderimpl.cpp | 8 +-- src/base/bittorrent/sessionimpl.cpp | 74 +++++++++++------------ src/base/bittorrent/sessionimpl.h | 9 ++- 3 files changed, 42 insertions(+), 49 deletions(-) diff --git a/src/base/bittorrent/portforwarderimpl.cpp b/src/base/bittorrent/portforwarderimpl.cpp index a6b9e3275..6ed58329e 100644 --- a/src/base/bittorrent/portforwarderimpl.cpp +++ b/src/base/bittorrent/portforwarderimpl.cpp @@ -107,10 +107,10 @@ void PortForwarderImpl::removePorts(const QString &profile) void PortForwarderImpl::start() { - lt::settings_pack settingsPack = m_provider->get_settings(); + lt::settings_pack settingsPack; settingsPack.set_bool(lt::settings_pack::enable_upnp, true); settingsPack.set_bool(lt::settings_pack::enable_natpmp, true); - m_provider->apply_settings(settingsPack); + m_provider->apply_settings(std::move(settingsPack)); for (auto profileIter = m_portProfiles.begin(); profileIter != m_portProfiles.end(); ++profileIter) { @@ -129,10 +129,10 @@ void PortForwarderImpl::start() void PortForwarderImpl::stop() { - lt::settings_pack settingsPack = m_provider->get_settings(); + lt::settings_pack settingsPack; settingsPack.set_bool(lt::settings_pack::enable_upnp, false); settingsPack.set_bool(lt::settings_pack::enable_natpmp, false); - m_provider->apply_settings(settingsPack); + m_provider->apply_settings(std::move(settingsPack)); // don't clear m_portProfiles so a later `start()` call can restore the port forwardings for (auto profileIter = m_portProfiles.begin(); profileIter != m_portProfiles.end(); ++profileIter) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 0bc64d05b..e8e701476 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1066,25 +1066,25 @@ void SessionImpl::adjustLimits() { if (isQueueingSystemEnabled()) { - lt::settings_pack settingsPack = m_nativeSession->get_settings(); - adjustLimits(settingsPack); - m_nativeSession->apply_settings(settingsPack); + lt::settings_pack settingsPack; + // Internally increase the queue limits to ensure that the magnet is started + settingsPack.set_int(lt::settings_pack::active_downloads, adjustLimit(maxActiveDownloads())); + settingsPack.set_int(lt::settings_pack::active_limit, adjustLimit(maxActiveTorrents())); + m_nativeSession->apply_settings(std::move(settingsPack)); } } void SessionImpl::applyBandwidthLimits() { - lt::settings_pack settingsPack = m_nativeSession->get_settings(); - applyBandwidthLimits(settingsPack); - m_nativeSession->apply_settings(settingsPack); + lt::settings_pack settingsPack; + settingsPack.set_int(lt::settings_pack::download_rate_limit, downloadSpeedLimit()); + settingsPack.set_int(lt::settings_pack::upload_rate_limit, uploadSpeedLimit()); + m_nativeSession->apply_settings(std::move(settingsPack)); } void SessionImpl::configure() { - lt::settings_pack settingsPack = m_nativeSession->get_settings(); - loadLTSettings(settingsPack); - m_nativeSession->apply_settings(settingsPack); - + m_nativeSession->apply_settings(loadLTSettings()); configureComponents(); m_deferredConfigureScheduled = false; @@ -1430,10 +1430,11 @@ void SessionImpl::endStartup(ResumeSessionContext *context) void SessionImpl::initializeNativeSession() { - const std::string peerId = lt::generate_fingerprint(PEER_ID, QBT_VERSION_MAJOR, QBT_VERSION_MINOR, QBT_VERSION_BUGFIX, QBT_VERSION_BUILD); + lt::settings_pack pack = loadLTSettings(); - lt::settings_pack pack; + const std::string peerId = lt::generate_fingerprint(PEER_ID, QBT_VERSION_MAJOR, QBT_VERSION_MINOR, QBT_VERSION_BUGFIX, QBT_VERSION_BUILD); pack.set_str(lt::settings_pack::peer_fingerprint, peerId); + pack.set_bool(lt::settings_pack::listen_system_port_fallback, false); pack.set_str(lt::settings_pack::user_agent, USER_AGENT.toStdString()); pack.set_bool(lt::settings_pack::use_dht_as_fallback, false); @@ -1450,8 +1451,7 @@ void SessionImpl::initializeNativeSession() pack.set_bool(lt::settings_pack::enable_set_file_valid_data, true); #endif - loadLTSettings(pack); - lt::session_params sessionParams {pack, {}}; + lt::session_params sessionParams {std::move(pack), {}}; #ifdef QBT_USES_LIBTORRENT2 switch (diskIOType()) { @@ -1509,28 +1509,14 @@ void SessionImpl::processBannedIPs(lt::ip_filter &filter) } } -void SessionImpl::adjustLimits(lt::settings_pack &settingsPack) const +int SessionImpl::adjustLimit(const int limit) const { - // Internally increase the queue limits to ensure that the magnet is started - const auto adjustLimit = [this](const int limit) -> int - { - if (limit <= -1) - return limit; - // check for overflow: (limit + m_extraLimit) < std::numeric_limits::max() - return (m_extraLimit < (std::numeric_limits::max() - limit)) - ? (limit + m_extraLimit) - : std::numeric_limits::max(); - }; - - settingsPack.set_int(lt::settings_pack::active_downloads, adjustLimit(maxActiveDownloads())); - settingsPack.set_int(lt::settings_pack::active_limit, adjustLimit(maxActiveTorrents())); -} - -void SessionImpl::applyBandwidthLimits(lt::settings_pack &settingsPack) const -{ - const bool altSpeedLimitEnabled = isAltGlobalSpeedLimitEnabled(); - settingsPack.set_int(lt::settings_pack::download_rate_limit, altSpeedLimitEnabled ? altGlobalDownloadSpeedLimit() : globalDownloadSpeedLimit()); - settingsPack.set_int(lt::settings_pack::upload_rate_limit, altSpeedLimitEnabled ? altGlobalUploadSpeedLimit() : globalUploadSpeedLimit()); + if (limit <= -1) + return limit; + // check for overflow: (limit + m_extraLimit) < std::numeric_limits::max() + return (m_extraLimit < (std::numeric_limits::max() - limit)) + ? (limit + m_extraLimit) + : std::numeric_limits::max(); } void SessionImpl::initMetrics() @@ -1575,8 +1561,10 @@ void SessionImpl::initMetrics() m_metricIndices.disk.diskJobTime = findMetricIndex("disk.disk_job_time"); } -void SessionImpl::loadLTSettings(lt::settings_pack &settingsPack) +lt::settings_pack SessionImpl::loadLTSettings() const { + lt::settings_pack settingsPack; + const lt::alert_category_t alertMask = lt::alert::error_notification | lt::alert::file_progress_notification | lt::alert::ip_block_notification @@ -1594,8 +1582,10 @@ void SessionImpl::loadLTSettings(lt::settings_pack &settingsPack) // It will not take affect until the listen_interfaces settings is updated settingsPack.set_int(lt::settings_pack::listen_queue_size, socketBacklogSize()); - configureNetworkInterfaces(settingsPack); - applyBandwidthLimits(settingsPack); + applyNetworkInterfacesSettings(settingsPack); + + settingsPack.set_int(lt::settings_pack::download_rate_limit, downloadSpeedLimit()); + settingsPack.set_int(lt::settings_pack::upload_rate_limit, uploadSpeedLimit()); // The most secure, rc4 only so that all streams are encrypted settingsPack.set_int(lt::settings_pack::allowed_enc_level, lt::settings_pack::pe_rc4); @@ -1730,7 +1720,9 @@ void SessionImpl::loadLTSettings(lt::settings_pack &settingsPack) // Queueing System if (isQueueingSystemEnabled()) { - adjustLimits(settingsPack); + // Internally increase the queue limits to ensure that the magnet is started + settingsPack.set_int(lt::settings_pack::active_downloads, adjustLimit(maxActiveDownloads())); + settingsPack.set_int(lt::settings_pack::active_limit, adjustLimit(maxActiveTorrents())); settingsPack.set_int(lt::settings_pack::active_seeds, maxActiveUploads()); settingsPack.set_bool(lt::settings_pack::dont_count_slow_torrents, ignoreSlowTorrentsForQueueing()); @@ -1846,9 +1838,11 @@ void SessionImpl::loadLTSettings(lt::settings_pack &settingsPack) settingsPack.set_int(lt::settings_pack::seed_choking_algorithm, lt::settings_pack::anti_leech); break; } + + return settingsPack; } -void SessionImpl::configureNetworkInterfaces(lt::settings_pack &settingsPack) +void SessionImpl::applyNetworkInterfacesSettings(lt::settings_pack &settingsPack) const { if (m_listenInterfaceConfigured) return; diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 578aa26c4..dd20a2812 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -474,11 +474,10 @@ namespace BitTorrent Q_INVOKABLE void configure(); void configureComponents(); void initializeNativeSession(); - void loadLTSettings(lt::settings_pack &settingsPack); - void configureNetworkInterfaces(lt::settings_pack &settingsPack); + lt::settings_pack loadLTSettings() const; + void applyNetworkInterfacesSettings(lt::settings_pack &settingsPack) const; void configurePeerClasses(); - void adjustLimits(lt::settings_pack &settingsPack) const; - void applyBandwidthLimits(lt::settings_pack &settingsPack) const; + int adjustLimit(int limit) const; void initMetrics(); void adjustLimits(); void applyBandwidthLimits(); @@ -553,7 +552,7 @@ namespace BitTorrent bool m_deferredConfigureScheduled = false; bool m_IPFilteringConfigured = false; - bool m_listenInterfaceConfigured = false; + mutable bool m_listenInterfaceConfigured = false; CachedSettingValue m_isDHTEnabled; CachedSettingValue m_isLSDEnabled;