Browse Source

Merge pull request #11307 from Chocobo1/session_conf

Clean up Session class configure routines
adaptive-webui-19844
Mike Tzou 5 years ago committed by GitHub
parent
commit
c1e0207454
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 282
      src/base/bittorrent/session.cpp
  2. 83
      src/base/bittorrent/session.h
  3. 2
      src/webui/api/synccontroller.cpp
  4. 4
      src/webui/api/torrentscontroller.cpp

282
src/base/bittorrent/session.cpp

@ -30,7 +30,6 @@
#include "session.h" #include "session.h"
#include <algorithm> #include <algorithm>
#include <cstdlib>
#include <queue> #include <queue>
#include <string> #include <string>
#include <utility> #include <utility>
@ -42,8 +41,10 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QFile>
#include <QHostAddress> #include <QHostAddress>
#include <QNetworkAddressEntry> #include <QNetworkAddressEntry>
#include <QNetworkConfigurationManager>
#include <QNetworkInterface> #include <QNetworkInterface>
#include <QRegularExpression> #include <QRegularExpression>
#include <QString> #include <QString>
@ -243,9 +244,6 @@ Session *Session::m_instance = nullptr;
Session::Session(QObject *parent) Session::Session(QObject *parent)
: QObject(parent) : QObject(parent)
, m_deferredConfigureScheduled(false)
, m_IPFilteringChanged(false)
, m_listenInterfaceChanged(true)
, m_isDHTEnabled(BITTORRENT_SESSION_KEY("DHTEnabled"), true) , m_isDHTEnabled(BITTORRENT_SESSION_KEY("DHTEnabled"), true)
, m_isLSDEnabled(BITTORRENT_SESSION_KEY("LSDEnabled"), true) , m_isLSDEnabled(BITTORRENT_SESSION_KEY("LSDEnabled"), true)
, m_isPeXEnabled(BITTORRENT_SESSION_KEY("PeXEnabled"), true) , m_isPeXEnabled(BITTORRENT_SESSION_KEY("PeXEnabled"), true)
@ -346,10 +344,14 @@ Session::Session(QObject *parent)
return tmp; return tmp;
} }
) )
, m_wasPexEnabled(m_isPeXEnabled) , m_resumeFolderLock {new QFile {this}}
, m_numResumeData(0) , m_refreshTimer {new QTimer {this}}
, m_extraLimit(0) , m_seedingLimitTimer {new QTimer {this}}
, m_recentErroredTorrentsTimer(new QTimer(this)) , m_resumeDataTimer {new QTimer {this}}
, m_statistics {new Statistics {this}}
, m_ioThread {new QThread {this}}
, m_recentErroredTorrentsTimer {new QTimer {this}}
, m_networkManager {new QNetworkConfigurationManager {this}}
{ {
if (port() < 0) if (port() < 0)
m_port = Utils::Random::rand(1024, 65535); m_port = Utils::Random::rand(1024, 65535);
@ -358,97 +360,18 @@ Session::Session(QObject *parent)
m_recentErroredTorrentsTimer->setSingleShot(true); m_recentErroredTorrentsTimer->setSingleShot(true);
m_recentErroredTorrentsTimer->setInterval(1000); m_recentErroredTorrentsTimer->setInterval(1000);
connect(m_recentErroredTorrentsTimer, &QTimer::timeout, this, [this]() { m_recentErroredTorrents.clear(); }); connect(m_recentErroredTorrentsTimer, &QTimer::timeout
, this, [this]() { m_recentErroredTorrents.clear(); });
m_seedingLimitTimer = new QTimer(this);
m_seedingLimitTimer->setInterval(10000); m_seedingLimitTimer->setInterval(10000);
connect(m_seedingLimitTimer, &QTimer::timeout, this, &Session::processShareLimits); connect(m_seedingLimitTimer, &QTimer::timeout, this, &Session::processShareLimits);
// Set severity level of libtorrent session initializeNativeSession();
const LTAlertCategory alertMask = lt::alert::error_notification configureComponents();
| lt::alert::peer_notification
| lt::alert::port_mapping_notification
| lt::alert::storage_notification
| lt::alert::tracker_notification
| lt::alert::status_notification
| lt::alert::ip_block_notification
| lt::alert::performance_warning
| lt::alert::file_progress_notification;
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;
pack.set_int(lt::settings_pack::alert_mask, alertMask);
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);
pack.set_bool(lt::settings_pack::use_dht_as_fallback, false);
// Speed up exit
pack.set_int(lt::settings_pack::stop_tracker_timeout, 1);
pack.set_int(lt::settings_pack::auto_scrape_interval, 1200); // 20 minutes
pack.set_int(lt::settings_pack::auto_scrape_min_interval, 900); // 15 minutes
pack.set_int(lt::settings_pack::connection_speed, 20); // default is 10
pack.set_bool(lt::settings_pack::no_connect_privileged_ports, false);
// libtorrent 1.1 enables UPnP & NAT-PMP by default
// turn them off before `lt::session` ctor to avoid split second effects
pack.set_bool(lt::settings_pack::enable_upnp, false);
pack.set_bool(lt::settings_pack::enable_natpmp, false);
pack.set_bool(lt::settings_pack::upnp_ignore_nonrouters, true);
#if (LIBTORRENT_VERSION_NUM < 10200)
// Disable support for SSL torrents for now
pack.set_int(lt::settings_pack::ssl_listen, 0);
// To prevent ISPs from blocking seeding
pack.set_bool(lt::settings_pack::lazy_bitfields, true);
// Disk cache pool is rarely tested in libtorrent and doesn't free buffers
// Soon to be deprecated there
// More info: https://github.com/arvidn/libtorrent/issues/2251
pack.set_bool(lt::settings_pack::use_disk_cache_pool, false);
#endif
configure(pack);
m_nativeSession = new lt::session {pack, LTSessionFlags {0}};
m_nativeSession->set_alert_notify([this]()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QMetaObject::invokeMethod(this, &Session::readAlerts, Qt::QueuedConnection);
#else
QMetaObject::invokeMethod(this, "readAlerts", Qt::QueuedConnection);
#endif
});
configurePeerClasses();
// Enabling plugins
//m_nativeSession->add_extension(&lt::create_metadata_plugin);
m_nativeSession->add_extension(&lt::create_ut_metadata_plugin);
if (isPeXEnabled())
m_nativeSession->add_extension(&lt::create_ut_pex_plugin);
m_nativeSession->add_extension(&lt::create_smart_ban_plugin);
LogMsg(tr("Peer ID: ") + QString::fromStdString(peerId));
LogMsg(tr("HTTP User-Agent is '%1'").arg(USER_AGENT));
LogMsg(tr("DHT support [%1]").arg(isDHTEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("Local Peer Discovery support [%1]").arg(isLSDEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("PeX support [%1]").arg(isPeXEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("Anonymous mode [%1]").arg(isAnonymousModeEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("Encryption support [%1]").arg((encryption() == 0) ? tr("ON") :
((encryption() == 1) ? tr("FORCED") : tr("OFF"))), Log::INFO);
if (isBandwidthSchedulerEnabled()) if (isBandwidthSchedulerEnabled())
enableBandwidthScheduler(); enableBandwidthScheduler();
if (isIPFilteringEnabled()) {
// Manually banned IPs are handled in that function too(in the slots)
enableIPFilter();
}
else {
// Add the banned IPs
lt::ip_filter filter;
processBannedIPs(filter);
m_nativeSession->set_ip_filter(filter);
}
m_categories = map_cast(m_storedCategories); m_categories = map_cast(m_storedCategories);
if (isSubcategoriesEnabled()) { if (isSubcategoriesEnabled()) {
// if subcategories support changed manually // if subcategories support changed manually
@ -458,35 +381,31 @@ Session::Session(QObject *parent)
m_tags = QSet<QString>::fromList(m_storedTags.value()); m_tags = QSet<QString>::fromList(m_storedTags.value());
m_refreshTimer = new QTimer(this);
m_refreshTimer->setInterval(refreshInterval()); m_refreshTimer->setInterval(refreshInterval());
connect(m_refreshTimer, &QTimer::timeout, this, &Session::refresh); connect(m_refreshTimer, &QTimer::timeout, this, &Session::refresh);
m_refreshTimer->start(); m_refreshTimer->start();
m_statistics = new Statistics(this);
updateSeedingLimitTimer(); updateSeedingLimitTimer();
populateAdditionalTrackers(); populateAdditionalTrackers();
enableTracker(isTrackerEnabled()); enableTracker(isTrackerEnabled());
connect(Net::ProxyConfigurationManager::instance(), &Net::ProxyConfigurationManager::proxyConfigurationChanged connect(Net::ProxyConfigurationManager::instance()
, this, &Session::configureDeferred); , &Net::ProxyConfigurationManager::proxyConfigurationChanged
, this, &Session::configureDeferred);
// Network configuration monitor // Network configuration monitor
connect(&m_networkManager, &QNetworkConfigurationManager::onlineStateChanged, this, &Session::networkOnlineStateChanged); connect(m_networkManager, &QNetworkConfigurationManager::onlineStateChanged, this, &Session::networkOnlineStateChanged);
connect(&m_networkManager, &QNetworkConfigurationManager::configurationAdded, this, &Session::networkConfigurationChange); connect(m_networkManager, &QNetworkConfigurationManager::configurationAdded, this, &Session::networkConfigurationChange);
connect(&m_networkManager, &QNetworkConfigurationManager::configurationRemoved, this, &Session::networkConfigurationChange); connect(m_networkManager, &QNetworkConfigurationManager::configurationRemoved, this, &Session::networkConfigurationChange);
connect(&m_networkManager, &QNetworkConfigurationManager::configurationChanged, this, &Session::networkConfigurationChange); connect(m_networkManager, &QNetworkConfigurationManager::configurationChanged, this, &Session::networkConfigurationChange);
m_ioThread = new QThread(this);
m_resumeDataSavingManager = new ResumeDataSavingManager {m_resumeFolderPath}; m_resumeDataSavingManager = new ResumeDataSavingManager {m_resumeFolderPath};
m_resumeDataSavingManager->moveToThread(m_ioThread); m_resumeDataSavingManager->moveToThread(m_ioThread);
connect(m_ioThread, &QThread::finished, m_resumeDataSavingManager, &QObject::deleteLater); connect(m_ioThread, &QThread::finished, m_resumeDataSavingManager, &QObject::deleteLater);
m_ioThread->start(); m_ioThread->start();
// Regular saving of fastresume data // Regular saving of fastresume data
m_resumeDataTimer = new QTimer(this);
connect(m_resumeDataTimer, &QTimer::timeout, this, [this]() { generateResumeData(); }); connect(m_resumeDataTimer, &QTimer::timeout, this, [this]() { generateResumeData(); });
const uint saveInterval = saveResumeDataInterval(); const uint saveInterval = saveResumeDataInterval();
if (saveInterval > 0) { if (saveInterval > 0) {
@ -498,8 +417,6 @@ Session::Session(QObject *parent)
new PortForwarderImpl {m_nativeSession}; new PortForwarderImpl {m_nativeSession};
initMetrics(); initMetrics();
qDebug("* BitTorrent Session constructed");
} }
bool Session::isDHTEnabled() const bool Session::isDHTEnabled() const
@ -667,7 +584,7 @@ QStringList Session::expandCategory(const QString &category)
return result; return result;
} }
const QStringMap &Session::categories() const QStringMap Session::categories() const
{ {
return m_categories; return m_categories;
} }
@ -948,8 +865,8 @@ Session::~Session()
m_ioThread->quit(); m_ioThread->quit();
m_ioThread->wait(); m_ioThread->wait();
m_resumeFolderLock.close(); m_resumeFolderLock->close();
m_resumeFolderLock.remove(); m_resumeFolderLock->remove();
} }
void Session::initInstance() void Session::initInstance()
@ -987,25 +904,102 @@ void Session::applyBandwidthLimits()
m_nativeSession->apply_settings(settingsPack); m_nativeSession->apply_settings(settingsPack);
} }
// Set BitTorrent session configuration
void Session::configure() void Session::configure()
{ {
qDebug("Configuring session");
lt::settings_pack settingsPack = m_nativeSession->get_settings(); lt::settings_pack settingsPack = m_nativeSession->get_settings();
configure(settingsPack); loadLTSettings(settingsPack);
m_nativeSession->apply_settings(settingsPack); m_nativeSession->apply_settings(settingsPack);
configureComponents();
m_deferredConfigureScheduled = false;
}
void Session::configureComponents()
{
// This function contains components/actions that:
// 1. Need to be setup at start up
// 2. When deferred configure is called
configurePeerClasses(); configurePeerClasses();
if (m_IPFilteringChanged) { if (!m_IPFilteringConfigured) {
if (isIPFilteringEnabled()) if (isIPFilteringEnabled())
enableIPFilter(); enableIPFilter();
else else
disableIPFilter(); disableIPFilter();
m_IPFilteringChanged = false; m_IPFilteringConfigured = true;
} }
}
m_deferredConfigureScheduled = false; void Session::initializeNativeSession()
qDebug("Session configured"); {
const LTAlertCategory alertMask = lt::alert::error_notification
| lt::alert::file_progress_notification
| lt::alert::ip_block_notification
| lt::alert::peer_notification
| lt::alert::performance_warning
| lt::alert::port_mapping_notification
| lt::alert::status_notification
| lt::alert::storage_notification
| lt::alert::tracker_notification;
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;
pack.set_int(lt::settings_pack::alert_mask, alertMask);
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);
pack.set_bool(lt::settings_pack::use_dht_as_fallback, false);
// Speed up exit
pack.set_int(lt::settings_pack::stop_tracker_timeout, 1);
pack.set_int(lt::settings_pack::auto_scrape_interval, 1200); // 20 minutes
pack.set_int(lt::settings_pack::auto_scrape_min_interval, 900); // 15 minutes
pack.set_int(lt::settings_pack::connection_speed, 20); // default is 10
pack.set_bool(lt::settings_pack::no_connect_privileged_ports, false);
// libtorrent 1.1 enables UPnP & NAT-PMP by default
// turn them off before `lt::session` ctor to avoid split second effects
pack.set_bool(lt::settings_pack::enable_upnp, false);
pack.set_bool(lt::settings_pack::enable_natpmp, false);
pack.set_bool(lt::settings_pack::upnp_ignore_nonrouters, true);
#if (LIBTORRENT_VERSION_NUM < 10200)
// Disable support for SSL torrents for now
pack.set_int(lt::settings_pack::ssl_listen, 0);
// To prevent ISPs from blocking seeding
pack.set_bool(lt::settings_pack::lazy_bitfields, true);
// Disk cache pool is rarely tested in libtorrent and doesn't free buffers
// Soon to be deprecated there
// More info: https://github.com/arvidn/libtorrent/issues/2251
pack.set_bool(lt::settings_pack::use_disk_cache_pool, false);
#endif
loadLTSettings(pack);
m_nativeSession = new lt::session {pack, LTSessionFlags {0}};
LogMsg(tr("Peer ID: ") + QString::fromStdString(peerId));
LogMsg(tr("HTTP User-Agent is '%1'").arg(USER_AGENT));
LogMsg(tr("DHT support [%1]").arg(isDHTEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("Local Peer Discovery support [%1]").arg(isLSDEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("PeX support [%1]").arg(isPeXEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("Anonymous mode [%1]").arg(isAnonymousModeEnabled() ? tr("ON") : tr("OFF")), Log::INFO);
LogMsg(tr("Encryption support [%1]").arg((encryption() == 0) ? tr("ON") :
((encryption() == 1) ? tr("FORCED") : tr("OFF"))), Log::INFO);
m_nativeSession->set_alert_notify([this]()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QMetaObject::invokeMethod(this, &Session::readAlerts, Qt::QueuedConnection);
#else
QMetaObject::invokeMethod(this, "readAlerts", Qt::QueuedConnection);
#endif
});
// Enabling plugins
m_nativeSession->add_extension(&lt::create_smart_ban_plugin);
m_nativeSession->add_extension(&lt::create_ut_metadata_plugin);
if (isPeXEnabled())
m_nativeSession->add_extension(&lt::create_ut_pex_plugin);
} }
void Session::processBannedIPs(lt::ip_filter &filter) void Session::processBannedIPs(lt::ip_filter &filter)
@ -1117,7 +1111,7 @@ void Session::initMetrics()
Q_ASSERT(m_metricIndices.disk.diskJobTime >= 0); Q_ASSERT(m_metricIndices.disk.diskJobTime >= 0);
} }
void Session::configure(lt::settings_pack &settingsPack) void Session::loadLTSettings(lt::settings_pack &settingsPack)
{ {
// from libtorrent doc: // from libtorrent doc:
// It will not take affect until the listen_interfaces settings is updated // It will not take affect until the listen_interfaces settings is updated
@ -1126,7 +1120,7 @@ void Session::configure(lt::settings_pack &settingsPack)
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QString chosenIP; QString chosenIP;
#endif #endif
if (m_listenInterfaceChanged) { if (!m_listenInterfaceConfigured) {
const int port = useRandomPort() ? 0 : this->port(); const int port = useRandomPort() ? 0 : this->port();
if (port > 0) // user specified port if (port > 0) // user specified port
settingsPack.set_int(lt::settings_pack::max_retry_port_bind, 0); settingsPack.set_int(lt::settings_pack::max_retry_port_bind, 0);
@ -1182,7 +1176,7 @@ void Session::configure(lt::settings_pack &settingsPack)
settingsPack.set_str(lt::settings_pack::outgoing_interfaces, networkInterface().toStdString()); settingsPack.set_str(lt::settings_pack::outgoing_interfaces, networkInterface().toStdString());
#endif // Q_OS_WIN #endif // Q_OS_WIN
m_listenInterfaceChanged = false; m_listenInterfaceConfigured = true;
} }
applyBandwidthLimits(settingsPack); applyBandwidthLimits(settingsPack);
@ -2190,8 +2184,6 @@ void Session::generateResumeData(const bool final)
// Called on exit // Called on exit
void Session::saveResumeData() void Session::saveResumeData()
{ {
qDebug("Saving resume data...");
// Pause session // Pause session
m_nativeSession->pause(); m_nativeSession->pause();
@ -2200,14 +2192,14 @@ void Session::saveResumeData()
generateResumeData(true); generateResumeData(true);
while (m_numResumeData > 0) { while (m_numResumeData > 0) {
std::vector<lt::alert *> alerts; const std::vector<lt::alert *> alerts = getPendingAlerts(lt::seconds(30));
getPendingAlerts(alerts, 30 * 1000);
if (alerts.empty()) { if (alerts.empty()) {
fprintf(stderr, " aborting with %d outstanding torrents to save resume data for\n", m_numResumeData); LogMsg(tr("Error: Aborted saving resume data for %1 outstanding torrents.").arg(QString::number(m_numResumeData))
, Log::CRITICAL);
break; break;
} }
for (const auto a : alerts) { for (const lt::alert *a : alerts) {
switch (a->type()) { switch (a->type()) {
case lt::save_resume_data_failed_alert::alert_type: case lt::save_resume_data_failed_alert::alert_type:
case lt::save_resume_data_alert::alert_type: case lt::save_resume_data_alert::alert_type:
@ -2377,7 +2369,7 @@ QStringList Session::getListeningIPs() const
// the BitTorrent session will listen to // the BitTorrent session will listen to
void Session::configureListeningInterface() void Session::configureListeningInterface()
{ {
m_listenInterfaceChanged = true; m_listenInterfaceConfigured = false;
configureDeferred(); configureDeferred();
} }
@ -2703,7 +2695,7 @@ void Session::setIPFilteringEnabled(const bool enabled)
{ {
if (enabled != m_isIPFilteringEnabled) { if (enabled != m_isIPFilteringEnabled) {
m_isIPFilteringEnabled = enabled; m_isIPFilteringEnabled = enabled;
m_IPFilteringChanged = true; m_IPFilteringConfigured = false;
configureDeferred(); configureDeferred();
} }
} }
@ -2718,7 +2710,7 @@ void Session::setIPFilterFile(QString path)
path = Utils::Fs::toUniformPath(path); path = Utils::Fs::toUniformPath(path);
if (path != IPFilterFile()) { if (path != IPFilterFile()) {
m_IPFilterFile = path; m_IPFilterFile = path;
m_IPFilteringChanged = true; m_IPFilteringConfigured = false;
configureDeferred(); configureDeferred();
} }
} }
@ -2752,7 +2744,7 @@ void Session::setBannedIPs(const QStringList &newList)
// also here we have to recreate filter list including 3rd party ban file // also here we have to recreate filter list including 3rd party ban file
// and install it again into m_session // and install it again into m_session
m_bannedIPs = filteredList; m_bannedIPs = filteredList;
m_IPFilteringChanged = true; m_IPFilteringConfigured = false;
configureDeferred(); configureDeferred();
} }
@ -3561,8 +3553,8 @@ void Session::initResumeFolder()
m_resumeFolderPath = Utils::Fs::expandPathAbs(specialFolderLocation(SpecialFolder::Data) + RESUME_FOLDER); m_resumeFolderPath = Utils::Fs::expandPathAbs(specialFolderLocation(SpecialFolder::Data) + RESUME_FOLDER);
const QDir resumeFolderDir(m_resumeFolderPath); const QDir resumeFolderDir(m_resumeFolderPath);
if (resumeFolderDir.exists() || resumeFolderDir.mkpath(resumeFolderDir.absolutePath())) { if (resumeFolderDir.exists() || resumeFolderDir.mkpath(resumeFolderDir.absolutePath())) {
m_resumeFolderLock.setFileName(resumeFolderDir.absoluteFilePath("session.lock")); m_resumeFolderLock->setFileName(resumeFolderDir.absoluteFilePath("session.lock"));
if (!m_resumeFolderLock.open(QFile::WriteOnly)) { if (!m_resumeFolderLock->open(QFile::WriteOnly)) {
throw RuntimeError {tr("Cannot write to torrent resume folder.")}; throw RuntimeError {tr("Cannot write to torrent resume folder.")};
} }
} }
@ -3573,16 +3565,17 @@ void Session::initResumeFolder()
void Session::configureDeferred() void Session::configureDeferred()
{ {
if (!m_deferredConfigureScheduled) { if (m_deferredConfigureScheduled)
return;
m_deferredConfigureScheduled = true;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QMetaObject::invokeMethod(this QMetaObject::invokeMethod(this
, qOverload<>(&Session::configure) , qOverload<>(&Session::configure)
, Qt::QueuedConnection); , Qt::QueuedConnection);
#else #else
QMetaObject::invokeMethod(this, "configure", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "configure", Qt::QueuedConnection);
#endif #endif
m_deferredConfigureScheduled = true;
}
} }
// Enable IP Filtering // Enable IP Filtering
@ -3816,13 +3809,14 @@ void Session::handleIPFilterError()
emit IPFilterParsed(true, 0); emit IPFilterParsed(true, 0);
} }
void Session::getPendingAlerts(std::vector<lt::alert *> &out, const ulong time) std::vector<lt::alert *> Session::getPendingAlerts(const lt::time_duration time) const
{ {
Q_ASSERT(out.empty()); if (time > lt::time_duration::zero())
m_nativeSession->wait_for_alert(time);
if (time > 0) std::vector<lt::alert *> alerts;
m_nativeSession->wait_for_alert(lt::milliseconds(time)); m_nativeSession->pop_alerts(&alerts);
m_nativeSession->pop_alerts(&out); return alerts;
} }
bool Session::isCreateTorrentSubfolder() const bool Session::isCreateTorrentSubfolder() const
@ -3838,10 +3832,8 @@ void Session::setCreateTorrentSubfolder(const bool value)
// Read alerts sent by the BitTorrent session // Read alerts sent by the BitTorrent session
void Session::readAlerts() void Session::readAlerts()
{ {
std::vector<lt::alert *> alerts; const std::vector<lt::alert *> alerts = getPendingAlerts();
getPendingAlerts(alerts); for (const lt::alert *a : alerts)
for (const auto a : alerts)
handleAlert(a); handleAlert(a);
} }

83
src/base/bittorrent/session.h

@ -34,9 +34,7 @@
#include <libtorrent/fwd.hpp> #include <libtorrent/fwd.hpp>
#include <QFile>
#include <QHash> #include <QHash>
#include <QNetworkConfigurationManager>
#include <QPointer> #include <QPointer>
#include <QSet> #include <QSet>
#include <QVector> #include <QVector>
@ -48,16 +46,19 @@
#include "sessionstatus.h" #include "sessionstatus.h"
#include "torrentinfo.h" #include "torrentinfo.h"
class QThread; class QFile;
class QTimer; class QNetworkConfiguration;
class QNetworkConfigurationManager;
class QString; class QString;
class QStringList; class QStringList;
class QThread;
class QTimer;
class QUrl; class QUrl;
class FilterParserThread;
class BandwidthScheduler; class BandwidthScheduler;
class Statistics; class FilterParserThread;
class ResumeDataSavingManager; class ResumeDataSavingManager;
class Statistics;
// These values should remain unchanged when adding new items // These values should remain unchanged when adding new items
// so as not to break the existing user settings. // so as not to break the existing user settings.
@ -89,9 +90,9 @@ namespace Net
namespace BitTorrent namespace BitTorrent
{ {
class InfoHash; class InfoHash;
class MagnetUri;
class TorrentHandle; class TorrentHandle;
class Tracker; class Tracker;
class MagnetUri;
class TrackerEntry; class TrackerEntry;
struct CreateTorrentParams; struct CreateTorrentParams;
@ -102,6 +103,14 @@ namespace BitTorrent
{ {
Q_NAMESPACE Q_NAMESPACE
enum class BTProtocol : int
{
Both = 0,
TCP = 1,
UTP = 2
};
Q_ENUM_NS(BTProtocol)
enum class ChokingAlgorithm : int enum class ChokingAlgorithm : int
{ {
FixedSlots = 0, FixedSlots = 0,
@ -109,14 +118,6 @@ namespace BitTorrent
}; };
Q_ENUM_NS(ChokingAlgorithm) Q_ENUM_NS(ChokingAlgorithm)
enum class SeedChokingAlgorithm : int
{
RoundRobin = 0,
FastestUpload = 1,
AntiLeech = 2
};
Q_ENUM_NS(SeedChokingAlgorithm)
enum class MixedModeAlgorithm : int enum class MixedModeAlgorithm : int
{ {
TCP = 0, TCP = 0,
@ -124,13 +125,13 @@ namespace BitTorrent
}; };
Q_ENUM_NS(MixedModeAlgorithm) Q_ENUM_NS(MixedModeAlgorithm)
enum class BTProtocol : int enum class SeedChokingAlgorithm : int
{ {
Both = 0, RoundRobin = 0,
TCP = 1, FastestUpload = 1,
UTP = 2 AntiLeech = 2
}; };
Q_ENUM_NS(BTProtocol) Q_ENUM_NS(SeedChokingAlgorithm)
} }
using namespace SessionSettingsEnums; using namespace SessionSettingsEnums;
@ -200,7 +201,7 @@ namespace BitTorrent
// returns category itself and all top level categories // returns category itself and all top level categories
static QStringList expandCategory(const QString &category); static QStringList expandCategory(const QString &category);
const QStringMap &categories() const; QStringMap categories() const;
QString categorySavePath(const QString &categoryName) const; QString categorySavePath(const QString &categoryName) const;
bool addCategory(const QString &name, const QString &savePath = ""); bool addCategory(const QString &name, const QString &savePath = "");
bool editCategory(const QString &name, const QString &savePath); bool editCategory(const QString &name, const QString &savePath);
@ -492,7 +493,7 @@ namespace BitTorrent
// Session reconfiguration triggers // Session reconfiguration triggers
void networkOnlineStateChanged(bool online); void networkOnlineStateChanged(bool online);
void networkConfigurationChange(const QNetworkConfiguration&); void networkConfigurationChange(const QNetworkConfiguration &);
private: private:
struct RemovingTorrentData struct RemovingTorrentData
@ -512,7 +513,9 @@ namespace BitTorrent
// Session configuration // Session configuration
Q_INVOKABLE void configure(); Q_INVOKABLE void configure();
void configure(lt::settings_pack &settingsPack); void configureComponents();
void initializeNativeSession();
void loadLTSettings(lt::settings_pack &settingsPack);
void configurePeerClasses(); void configurePeerClasses();
void adjustLimits(lt::settings_pack &settingsPack); void adjustLimits(lt::settings_pack &settingsPack);
void applyBandwidthLimits(lt::settings_pack &settingsPack) const; void applyBandwidthLimits(lt::settings_pack &settingsPack) const;
@ -565,14 +568,14 @@ namespace BitTorrent
void saveTorrentsQueue(); void saveTorrentsQueue();
void removeTorrentsQueue(); void removeTorrentsQueue();
void getPendingAlerts(std::vector<lt::alert *> &out, ulong time = 0); std::vector<lt::alert *> getPendingAlerts(lt::time_duration time = lt::time_duration::zero()) const;
// BitTorrent // BitTorrent
lt::session *m_nativeSession; lt::session *m_nativeSession = nullptr;
bool m_deferredConfigureScheduled; bool m_deferredConfigureScheduled = false;
bool m_IPFilteringChanged; bool m_IPFilteringConfigured = false;
bool m_listenInterfaceChanged; // optimization bool m_listenInterfaceConfigured = false;
CachedSettingValue<bool> m_isDHTEnabled; CachedSettingValue<bool> m_isDHTEnabled;
CachedSettingValue<bool> m_isLSDEnabled; CachedSettingValue<bool> m_isLSDEnabled;
@ -662,26 +665,26 @@ namespace BitTorrent
// Order is important. This needs to be declared after its CachedSettingsValue // Order is important. This needs to be declared after its CachedSettingsValue
// counterpart, because it uses it for initialization in the constructor // counterpart, because it uses it for initialization in the constructor
// initialization list. // initialization list.
const bool m_wasPexEnabled; const bool m_wasPexEnabled = m_isPeXEnabled;
int m_numResumeData; int m_numResumeData = 0;
int m_extraLimit; int m_extraLimit = 0;
QVector<BitTorrent::TrackerEntry> m_additionalTrackerList; QVector<BitTorrent::TrackerEntry> m_additionalTrackerList;
QString m_resumeFolderPath; QString m_resumeFolderPath;
QFile m_resumeFolderLock; QFile *m_resumeFolderLock = nullptr;
QTimer *m_refreshTimer; QTimer *m_refreshTimer = nullptr;
QTimer *m_seedingLimitTimer; QTimer *m_seedingLimitTimer = nullptr;
QTimer *m_resumeDataTimer; QTimer *m_resumeDataTimer = nullptr;
Statistics *m_statistics; Statistics *m_statistics = nullptr;
// IP filtering // IP filtering
QPointer<FilterParserThread> m_filterParser; QPointer<FilterParserThread> m_filterParser;
QPointer<BandwidthScheduler> m_bwScheduler; QPointer<BandwidthScheduler> m_bwScheduler;
// Tracker // Tracker
QPointer<Tracker> m_tracker; QPointer<Tracker> m_tracker;
// fastresume data writing thread // fastresume data writing thread
QThread *m_ioThread; QThread *m_ioThread = nullptr;
ResumeDataSavingManager *m_resumeDataSavingManager; ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
QHash<InfoHash, TorrentInfo> m_loadedMetadata; QHash<InfoHash, TorrentInfo> m_loadedMetadata;
QHash<InfoHash, TorrentHandle *> m_torrents; QHash<InfoHash, TorrentHandle *> m_torrents;
@ -693,7 +696,7 @@ namespace BitTorrent
// I/O errored torrents // I/O errored torrents
QSet<InfoHash> m_recentErroredTorrents; QSet<InfoHash> m_recentErroredTorrents;
QTimer *m_recentErroredTorrentsTimer; QTimer *m_recentErroredTorrentsTimer = nullptr;
SessionMetricIndices m_metricIndices; SessionMetricIndices m_metricIndices;
lt::time_point m_statsLastTimestamp = lt::clock_type::now(); lt::time_point m_statsLastTimestamp = lt::clock_type::now();
@ -701,7 +704,7 @@ namespace BitTorrent
SessionStatus m_status; SessionStatus m_status;
CacheStatus m_cacheStatus; CacheStatus m_cacheStatus;
QNetworkConfigurationManager m_networkManager; QNetworkConfigurationManager *m_networkManager = nullptr;
static Session *m_instance; static Session *m_instance;
}; };

2
src/webui/api/synccontroller.cpp

@ -446,7 +446,7 @@ void SyncController::maindataAction()
data["torrents"] = torrents; data["torrents"] = torrents;
QVariantHash categories; QVariantHash categories;
const auto &categoriesList = session->categories(); const QStringMap categoriesList = session->categories();
for (auto it = categoriesList.cbegin(); it != categoriesList.cend(); ++it) { for (auto it = categoriesList.cbegin(); it != categoriesList.cend(); ++it) {
const QString &key = it.key(); const QString &key = it.key();
categories[key] = QVariantMap { categories[key] = QVariantMap {

4
src/webui/api/torrentscontroller.cpp

@ -1077,8 +1077,8 @@ void TorrentsController::removeCategoriesAction()
void TorrentsController::categoriesAction() void TorrentsController::categoriesAction()
{ {
QJsonObject categories; QJsonObject categories;
const auto categoriesList = BitTorrent::Session::instance()->categories(); const QStringMap categoriesMap = BitTorrent::Session::instance()->categories();
for (auto it = categoriesList.cbegin(); it != categoriesList.cend(); ++it) { for (auto it = categoriesMap.cbegin(); it != categoriesMap.cend(); ++it) {
const auto &key = it.key(); const auto &key = it.key();
categories[key] = QJsonObject { categories[key] = QJsonObject {
{"name", key}, {"name", key},

Loading…
Cancel
Save