Browse Source

Improve BandwidthScheduler

Don't disable scheduler when manually switching speed limits.
Closes #7306.
adaptive-webui-19844
Vladimir Golovnev (qlassez) 7 years ago
parent
commit
93f5d4058d
No known key found for this signature in database
GPG Key ID: 52A2C7DEE2DFA6F7
  1. 75
      src/base/bittorrent/private/bandwidthscheduler.cpp
  2. 22
      src/base/bittorrent/private/bandwidthscheduler.h
  3. 71
      src/base/bittorrent/session.cpp
  4. 5
      src/base/bittorrent/session.h
  5. 2
      src/gui/mainwindow.cpp
  6. 2
      src/gui/optionsdlg.cpp

75
src/base/bittorrent/private/bandwidthscheduler.cpp

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2010 Christophe Dumez
* Copyright (C) 2017 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -24,72 +25,78 @@ @@ -24,72 +25,78 @@
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include "bandwidthscheduler.h"
#include <utility>
#include <QDate>
#include <QTime>
#include <QDateTime>
#include "base/bittorrent/session.h"
#include "base/preferences.h"
#include "bandwidthscheduler.h"
BandwidthScheduler::BandwidthScheduler(QObject *parent)
: QTimer(parent)
: QObject(parent)
, m_lastAlternative(false)
{
// Single shot, we call start() again manually
setSingleShot(true);
// Connect Signals/Slots
connect(this, SIGNAL(timeout()), this, SLOT(start()));
connect(&m_timer, &QTimer::timeout, this, &BandwidthScheduler::onTimeout);
}
void BandwidthScheduler::start()
{
m_lastAlternative = isTimeForAlternative();
emit bandwidthLimitRequested(m_lastAlternative);
// Timeout regularly to accommodate for external system clock changes
// eg from the user or from a timesync utility
m_timer.start(30000);
}
bool BandwidthScheduler::isTimeForAlternative() const
{
const Preferences* const pref = Preferences::instance();
bool alt_bw_enabled = BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled();
QTime start = pref->getSchedulerStartTime();
QTime end = pref->getSchedulerEndTime();
QTime now = QTime::currentTime();
int sched_days = pref->getSchedulerDays();
int day = QDateTime::currentDateTime().toLocalTime().date().dayOfWeek();
bool new_mode = false;
bool reverse = false;
const QTime now = QTime::currentTime();
const int schedulerDays = pref->getSchedulerDays();
const int day = QDate::currentDate().dayOfWeek();
bool alternative = false;
if (start > end) {
QTime temp = start;
start = end;
end = temp;
reverse = true;
std::swap(start, end);
alternative = true;
}
if ((start <= now) && (end >= now)) {
switch(sched_days) {
switch (schedulerDays) {
case EVERY_DAY:
new_mode = true;
alternative = !alternative;
break;
case WEEK_ENDS:
if ((day == 6) || (day == 7))
new_mode = true;
alternative = !alternative;
break;
case WEEK_DAYS:
if ((day != 6) && (day != 7))
new_mode = true;
alternative = !alternative;
break;
default:
if (day == (sched_days - 2))
new_mode = true;
if (day == (schedulerDays - 2))
alternative = !alternative;
}
}
if (reverse)
new_mode = !new_mode;
return alternative;
}
if (new_mode != alt_bw_enabled)
emit switchToAlternativeMode(new_mode);
void BandwidthScheduler::onTimeout()
{
bool alternative = isTimeForAlternative();
// Timeout regularly to accommodate for external system clock changes
// eg from the user or from a timesync utility
QTimer::start(1500);
if (alternative != m_lastAlternative) {
m_lastAlternative = alternative;
emit bandwidthLimitRequested(alternative);
}
}

22
src/base/bittorrent/private/bandwidthscheduler.h

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2010 Christophe Dumez
* Copyright (C) 2017 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -24,27 +25,32 @@ @@ -24,27 +25,32 @@
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef BANDWIDTHSCHEDULER_H
#define BANDWIDTHSCHEDULER_H
#include <QObject>
#include <QTimer>
class BandwidthScheduler : public QTimer
class BandwidthScheduler: public QObject
{
Q_OBJECT
Q_DISABLE_COPY(BandwidthScheduler)
public:
BandwidthScheduler(QObject *parent = 0);
public slots:
explicit BandwidthScheduler(QObject *parent = nullptr);
void start();
signals:
void switchToAlternativeMode(bool alternative);
void bandwidthLimitRequested(bool alternative);
private:
bool isTimeForAlternative() const;
void onTimeout();
QTimer m_timer;
bool m_lastAlternative;
};
#endif // BANDWIDTHSCHEDULER_H

71
src/base/bittorrent/session.cpp

@ -441,6 +441,9 @@ Session::Session(QObject *parent) @@ -441,6 +441,9 @@ Session::Session(QObject *parent)
.arg(encryption() == 0 ? tr("ON") : encryption() == 1 ? tr("FORCED") : tr("OFF"))
, Log::INFO);
if (isBandwidthSchedulerEnabled())
enableBandwidthScheduler();
if (isIPFilteringEnabled()) {
// Manually banned IPs are handled in that function too(in the slots)
enableIPFilter();
@ -953,13 +956,8 @@ Session::~Session() @@ -953,13 +956,8 @@ Session::~Session()
void Session::initInstance()
{
if (!m_instance) {
if (!m_instance)
m_instance = new Session;
// BandwidthScheduler::start() depends on Session being fully constructed
if (m_instance->isBandwidthSchedulerEnabled())
m_instance->enableBandwidthScheduler();
}
}
void Session::freeInstance()
@ -990,6 +988,19 @@ void Session::adjustLimits() @@ -990,6 +988,19 @@ void Session::adjustLimits()
}
}
void Session::applyBandwidthLimits()
{
#if LIBTORRENT_VERSION_NUM < 10100
libt::session_settings sessionSettings(m_nativeSession->settings());
applyBandwidthLimits(sessionSettings);
m_nativeSession->set_settings(sessionSettings);
#else
libt::settings_pack settingsPack = m_nativeSession->get_settings();
applyBandwidthLimits(settingsPack);
m_nativeSession->apply_settings(settingsPack);
#endif
}
// Set BitTorrent session configuration
void Session::configure()
{
@ -1042,6 +1053,13 @@ void Session::adjustLimits(libt::settings_pack &settingsPack) @@ -1042,6 +1053,13 @@ void Session::adjustLimits(libt::settings_pack &settingsPack)
, maxActive > -1 ? maxActive + m_extraLimit : maxActive);
}
void Session::applyBandwidthLimits(libtorrent::settings_pack &settingsPack)
{
const bool altSpeedLimitEnabled = isAltGlobalSpeedLimitEnabled();
settingsPack.set_int(libt::settings_pack::download_rate_limit, altSpeedLimitEnabled ? altGlobalDownloadSpeedLimit() : globalDownloadSpeedLimit());
settingsPack.set_int(libt::settings_pack::upload_rate_limit, altSpeedLimitEnabled ? altGlobalUploadSpeedLimit() : globalUploadSpeedLimit());
}
void Session::initMetrics()
{
m_metricIndices.net.hasIncomingConnections = libt::find_metric_idx("net.has_incoming_connections");
@ -1185,9 +1203,7 @@ void Session::configure(libtorrent::settings_pack &settingsPack) @@ -1185,9 +1203,7 @@ void Session::configure(libtorrent::settings_pack &settingsPack)
m_listenInterfaceChanged = false;
}
const bool altSpeedLimitEnabled = isAltGlobalSpeedLimitEnabled();
settingsPack.set_int(libt::settings_pack::download_rate_limit, altSpeedLimitEnabled ? altGlobalDownloadSpeedLimit() : globalDownloadSpeedLimit());
settingsPack.set_int(libt::settings_pack::upload_rate_limit, altSpeedLimitEnabled ? altGlobalUploadSpeedLimit() : globalUploadSpeedLimit());
applyBandwidthLimits(settingsPack);
// The most secure, rc4 only so that all streams are encrypted
settingsPack.set_int(libt::settings_pack::allowed_enc_level, libt::settings_pack::pe_rc4);
@ -1397,11 +1413,16 @@ void Session::adjustLimits(libt::session_settings &sessionSettings) @@ -1397,11 +1413,16 @@ void Session::adjustLimits(libt::session_settings &sessionSettings)
sessionSettings.active_limit = maxActive > -1 ? maxActive + m_extraLimit : maxActive;
}
void Session::configure(libtorrent::session_settings &sessionSettings)
void Session::applyBandwidthLimits(libt::session_settings &sessionSettings)
{
const bool altSpeedLimitEnabled = isAltGlobalSpeedLimitEnabled();
sessionSettings.download_rate_limit = altSpeedLimitEnabled ? altGlobalDownloadSpeedLimit() : globalDownloadSpeedLimit();
sessionSettings.upload_rate_limit = altSpeedLimitEnabled ? altGlobalUploadSpeedLimit() : globalUploadSpeedLimit();
}
void Session::configure(libtorrent::session_settings &sessionSettings)
{
applyBandwidthLimits(sessionSettings);
// The most secure, rc4 only so that all streams are encrypted
libt::pe_settings encryptionSettings;
@ -1568,7 +1589,8 @@ void Session::enableBandwidthScheduler() @@ -1568,7 +1589,8 @@ void Session::enableBandwidthScheduler()
{
if (!m_bwScheduler) {
m_bwScheduler = new BandwidthScheduler(this);
connect(m_bwScheduler.data(), SIGNAL(switchToAlternativeMode(bool)), this, SLOT(switchToAlternativeMode(bool)));
connect(m_bwScheduler.data(), &BandwidthScheduler::bandwidthLimitRequested
, this, &Session::setAltGlobalSpeedLimitEnabled);
}
m_bwScheduler->start();
}
@ -1650,11 +1672,6 @@ void Session::handleRedirectedToMagnet(const QString &url, const QString &magnet @@ -1650,11 +1672,6 @@ void Session::handleRedirectedToMagnet(const QString &url, const QString &magnet
addTorrent_impl(m_downloadedTorrents.take(url), MagnetUri(magnetUri));
}
void Session::switchToAlternativeMode(bool alternative)
{
changeSpeedLimitMode_impl(alternative);
}
// Add to BitTorrent session the downloaded torrent file
void Session::handleDownloadFinished(const QString &url, const QString &filePath)
{
@ -2147,18 +2164,6 @@ void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolde @@ -2147,18 +2164,6 @@ void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolde
}
}
void Session::changeSpeedLimitMode_impl(bool alternative)
{
qDebug() << Q_FUNC_INFO << alternative;
if (alternative == isAltGlobalSpeedLimitEnabled()) return;
// Save new state to remember it on startup
m_isAltGlobalSpeedLimitEnabled = alternative;
configureDeferred();
// Notify
emit speedLimitModeChanged(alternative);
}
void Session::generateResumeData(bool final)
{
foreach (TorrentHandle *const torrent, m_torrents) {
@ -2488,11 +2493,13 @@ bool Session::isAltGlobalSpeedLimitEnabled() const @@ -2488,11 +2493,13 @@ bool Session::isAltGlobalSpeedLimitEnabled() const
void Session::setAltGlobalSpeedLimitEnabled(bool enabled)
{
// Stop the scheduler when the user has manually changed the bandwidth mode
if (isBandwidthSchedulerEnabled())
setBandwidthSchedulerEnabled(false);
if (enabled == isAltGlobalSpeedLimitEnabled()) return;
changeSpeedLimitMode_impl(enabled);
// Save new state to remember it on startup
m_isAltGlobalSpeedLimitEnabled = enabled;
applyBandwidthLimits();
// Notify
emit speedLimitModeChanged(m_isAltGlobalSpeedLimitEnabled);
}
bool Session::isBandwidthSchedulerEnabled() const

5
src/base/bittorrent/session.h

@ -480,7 +480,6 @@ namespace BitTorrent @@ -480,7 +480,6 @@ namespace BitTorrent
void handleDownloadFinished(const QString &url, const QString &filePath);
void handleDownloadFailed(const QString &url, const QString &reason);
void handleRedirectedToMagnet(const QString &url, const QString &magnetUri);
void switchToAlternativeMode(bool alternative);
// Session reconfiguration triggers
void networkOnlineStateChanged(const bool online);
@ -500,17 +499,19 @@ namespace BitTorrent @@ -500,17 +499,19 @@ namespace BitTorrent
#if LIBTORRENT_VERSION_NUM < 10100
void configure(libtorrent::session_settings &sessionSettings);
void adjustLimits(libtorrent::session_settings &sessionSettings);
void applyBandwidthLimits(libtorrent::session_settings &sessionSettings);
#else
void configure(libtorrent::settings_pack &settingsPack);
void configurePeerClasses();
void adjustLimits(libtorrent::settings_pack &settingsPack);
void applyBandwidthLimits(libtorrent::settings_pack &settingsPack);
void initMetrics();
#endif
void adjustLimits();
void applyBandwidthLimits();
void processBannedIPs(libtorrent::ip_filter &filter);
const QStringList getListeningIPs();
void configureListeningInterface();
void changeSpeedLimitMode_impl(bool alternative);
void enableTracker(bool enable);
void enableBandwidthScheduler();
void populateAdditionalTrackers();

2
src/gui/mainwindow.cpp

@ -1831,8 +1831,6 @@ void MainWindow::handleUpdateCheckFinished(bool updateAvailable, QString newVers @@ -1831,8 +1831,6 @@ void MainWindow::handleUpdateCheckFinished(bool updateAvailable, QString newVers
void MainWindow::toggleAlternativeSpeeds()
{
BitTorrent::Session *const session = BitTorrent::Session::instance();
if (session->isBandwidthSchedulerEnabled())
m_statusBar->showMessage(tr("Manual change of rate limits mode. The scheduler is disabled."), 5000);
session->setAltGlobalSpeedLimitEnabled(!session->isAltGlobalSpeedLimitEnabled());
}

2
src/gui/optionsdlg.cpp

@ -586,10 +586,10 @@ void OptionsDialog::saveOptions() @@ -586,10 +586,10 @@ void OptionsDialog::saveOptions()
const QPair<int, int> alt_down_up_limit = getAltGlobalBandwidthLimits();
session->setAltGlobalDownloadSpeedLimit(alt_down_up_limit.first);
session->setAltGlobalUploadSpeedLimit(alt_down_up_limit.second);
session->setBandwidthSchedulerEnabled(m_ui->check_schedule->isChecked());
pref->setSchedulerStartTime(m_ui->schedule_from->time());
pref->setSchedulerEndTime(m_ui->schedule_to->time());
pref->setSchedulerDays(static_cast<scheduler_days>(m_ui->schedule_days->currentIndex()));
session->setBandwidthSchedulerEnabled(m_ui->check_schedule->isChecked());
auto proxyConfigManager = Net::ProxyConfigurationManager::instance();
Net::ProxyConfiguration proxyConf;

Loading…
Cancel
Save