Run worker pool at lowest thread priority (#1497)
This commit is contained in:
parent
d8b075dc0c
commit
edad7fad32
@ -243,6 +243,8 @@ set(SOURCES
|
|||||||
miscellaneous/templates.h
|
miscellaneous/templates.h
|
||||||
miscellaneous/textfactory.cpp
|
miscellaneous/textfactory.cpp
|
||||||
miscellaneous/textfactory.h
|
miscellaneous/textfactory.h
|
||||||
|
miscellaneous/thread.cpp
|
||||||
|
miscellaneous/thread.h
|
||||||
network-web/adblock/adblockdialog.cpp
|
network-web/adblock/adblockdialog.cpp
|
||||||
network-web/adblock/adblockdialog.h
|
network-web/adblock/adblockdialog.h
|
||||||
network-web/adblock/adblockicon.cpp
|
network-web/adblock/adblockicon.cpp
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "exceptions/filteringexception.h"
|
#include "exceptions/filteringexception.h"
|
||||||
#include "miscellaneous/application.h"
|
#include "miscellaneous/application.h"
|
||||||
#include "miscellaneous/settings.h"
|
#include "miscellaneous/settings.h"
|
||||||
|
#include "miscellaneous/thread.h"
|
||||||
#include "services/abstract/cacheforserviceroot.h"
|
#include "services/abstract/cacheforserviceroot.h"
|
||||||
#include "services/abstract/feed.h"
|
#include "services/abstract/feed.h"
|
||||||
#include "services/abstract/labelsnode.h"
|
#include "services/abstract/labelsnode.h"
|
||||||
@ -17,7 +18,6 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QJSEngine>
|
#include <QJSEngine>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QThread>
|
|
||||||
#include <QtConcurrentMap>
|
#include <QtConcurrentMap>
|
||||||
|
|
||||||
FeedDownloader::FeedDownloader()
|
FeedDownloader::FeedDownloader()
|
||||||
@ -47,7 +47,7 @@ void FeedDownloader::synchronizeAccountCaches(const QList<CacheForServiceRoot*>&
|
|||||||
|
|
||||||
for (CacheForServiceRoot* cache : caches) {
|
for (CacheForServiceRoot* cache : caches) {
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Synchronizing cache back to server on thread"
|
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Synchronizing cache back to server on thread"
|
||||||
<< QUOTE_W_SPACE_DOT(QThread::currentThreadId());
|
<< QUOTE_W_SPACE_DOT(getThreadID());
|
||||||
cache->saveAllCachedData(false);
|
cache->saveAllCachedData(false);
|
||||||
|
|
||||||
if (m_stopCacheSynchronization) {
|
if (m_stopCacheSynchronization) {
|
||||||
@ -77,7 +77,7 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Starting feed updates from worker in thread"
|
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Starting feed updates from worker in thread"
|
||||||
<< QUOTE_W_SPACE_DOT(QThread::currentThreadId());
|
<< QUOTE_W_SPACE_DOT(getThreadID());
|
||||||
|
|
||||||
// Job starts now.
|
// Job starts now.
|
||||||
emit updateStarted();
|
emit updateStarted();
|
||||||
@ -155,6 +155,9 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
|||||||
|
|
||||||
std::function<FeedUpdateResult(const FeedUpdateRequest&)> func =
|
std::function<FeedUpdateResult(const FeedUpdateRequest&)> func =
|
||||||
[=](const FeedUpdateRequest& fd) -> FeedUpdateResult {
|
[=](const FeedUpdateRequest& fd) -> FeedUpdateResult {
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
setThreadPriority(Priority::LOWEST);
|
||||||
|
#endif
|
||||||
return updateThreadedFeed(fd);
|
return updateThreadedFeed(fd);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -220,7 +223,7 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc,
|
|||||||
acc->itemChanged({feed});
|
acc->itemChanged({feed});
|
||||||
}
|
}
|
||||||
|
|
||||||
qlonglong thread_id = qlonglong(QThread::currentThreadId());
|
qlonglong thread_id = getThreadID();
|
||||||
|
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Downloading new messages for feed ID" << QUOTE_W_SPACE(feed->customId())
|
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Downloading new messages for feed ID" << QUOTE_W_SPACE(feed->customId())
|
||||||
<< "URL:" << QUOTE_W_SPACE(feed->source()) << "title:" << QUOTE_W_SPACE(feed->title()) << "in thread "
|
<< "URL:" << QUOTE_W_SPACE(feed->source()) << "title:" << QUOTE_W_SPACE(feed->title()) << "in thread "
|
||||||
@ -435,7 +438,7 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc,
|
|||||||
|
|
||||||
void FeedDownloader::finalizeUpdate() {
|
void FeedDownloader::finalizeUpdate() {
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Finished feed updates in thread"
|
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Finished feed updates in thread"
|
||||||
<< QUOTE_W_SPACE_DOT(QThread::currentThreadId());
|
<< QUOTE_W_SPACE_DOT(getThreadID());
|
||||||
|
|
||||||
m_feeds.clear();
|
m_feeds.clear();
|
||||||
|
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
#include "database/databasequeries.h"
|
#include "database/databasequeries.h"
|
||||||
#include "miscellaneous/application.h"
|
#include "miscellaneous/application.h"
|
||||||
|
#include "miscellaneous/thread.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
DatabaseCleaner::DatabaseCleaner(QObject* parent) : QObject(parent) {}
|
DatabaseCleaner::DatabaseCleaner(QObject* parent) : QObject(parent) {}
|
||||||
|
|
||||||
void DatabaseCleaner::purgeDatabaseData(CleanerOrders which_data) {
|
void DatabaseCleaner::purgeDatabaseData(CleanerOrders which_data) {
|
||||||
qDebugNN << LOGSEC_DB << "Performing database cleanup in thread:" << QUOTE_W_SPACE_DOT(QThread::currentThreadId());
|
qDebugNN << LOGSEC_DB << "Performing database cleanup in thread:" << QUOTE_W_SPACE_DOT(getThreadID());
|
||||||
|
|
||||||
// Inform everyone about the start of the process.
|
// Inform everyone about the start of the process.
|
||||||
emit purgeStarted();
|
emit purgeStarted();
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "definitions/definitions.h"
|
#include "definitions/definitions.h"
|
||||||
#include "exceptions/applicationexception.h"
|
#include "exceptions/applicationexception.h"
|
||||||
#include "miscellaneous/iofactory.h"
|
#include "miscellaneous/iofactory.h"
|
||||||
|
#include "miscellaneous/thread.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QSqlError>
|
#include <QSqlError>
|
||||||
@ -14,7 +15,7 @@
|
|||||||
DatabaseDriver::DatabaseDriver(QObject* parent) : QObject(parent) {}
|
DatabaseDriver::DatabaseDriver(QObject* parent) : QObject(parent) {}
|
||||||
|
|
||||||
QSqlDatabase DatabaseDriver::threadSafeConnection(const QString& connection_name, DesiredStorageType desired_type) {
|
QSqlDatabase DatabaseDriver::threadSafeConnection(const QString& connection_name, DesiredStorageType desired_type) {
|
||||||
qlonglong thread_id = qlonglong(QThread::currentThreadId());
|
qlonglong thread_id = getThreadID();
|
||||||
bool is_main_thread = QThread::currentThread() == qApp->thread();
|
bool is_main_thread = QThread::currentThread() == qApp->thread();
|
||||||
|
|
||||||
QSqlDatabase database =
|
QSqlDatabase database =
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
#include "miscellaneous/mutex.h"
|
#include "miscellaneous/mutex.h"
|
||||||
#include "miscellaneous/settings.h"
|
#include "miscellaneous/settings.h"
|
||||||
|
#include "miscellaneous/thread.h"
|
||||||
#include "network-web/adblock/adblockicon.h"
|
#include "network-web/adblock/adblockicon.h"
|
||||||
#include "network-web/adblock/adblockmanager.h"
|
#include "network-web/adblock/adblockmanager.h"
|
||||||
#include "network-web/webfactory.h"
|
#include "network-web/webfactory.h"
|
||||||
@ -38,7 +39,6 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <QThread>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QWidgetAction>
|
#include <QWidgetAction>
|
||||||
@ -54,7 +54,7 @@
|
|||||||
FormMain::FormMain(QWidget* parent, Qt::WindowFlags f)
|
FormMain::FormMain(QWidget* parent, Qt::WindowFlags f)
|
||||||
: QMainWindow(parent, f), m_ui(new Ui::FormMain), m_trayMenu(nullptr), m_statusBar(nullptr) {
|
: QMainWindow(parent, f), m_ui(new Ui::FormMain), m_trayMenu(nullptr), m_statusBar(nullptr) {
|
||||||
qDebugNN << LOGSEC_GUI
|
qDebugNN << LOGSEC_GUI
|
||||||
<< "Creating main application form in thread:" << QUOTE_W_SPACE_DOT(QThread::currentThreadId());
|
<< "Creating main application form in thread:" << QUOTE_W_SPACE_DOT(getThreadID());
|
||||||
// setAttribute(Qt::WA_WindowPropagation, true);
|
// setAttribute(Qt::WA_WindowPropagation, true);
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
qApp->setMainForm(this);
|
qApp->setMainForm(this);
|
||||||
|
@ -42,7 +42,7 @@ TextBrowserViewer::TextBrowserViewer(QWidget* parent)
|
|||||||
setDocument(m_document.data());
|
setDocument(m_document.data());
|
||||||
|
|
||||||
m_resourceDownloader->moveToThread(m_resourceDownloaderThread);
|
m_resourceDownloader->moveToThread(m_resourceDownloaderThread);
|
||||||
m_resourceDownloaderThread->start();
|
m_resourceDownloaderThread->start(QThread::LowPriority);
|
||||||
|
|
||||||
connect(this, &TextBrowserViewer::reloadDocument, this, [this]() {
|
connect(this, &TextBrowserViewer::reloadDocument, this, [this]() {
|
||||||
const auto scr = verticalScrollBarPosition();
|
const auto scr = verticalScrollBarPosition();
|
||||||
|
@ -1157,6 +1157,12 @@ void Application::setupWorkHorsePool() {
|
|||||||
m_workHorsePool->setMaxThreadCount((std::min)(MAX_THREADPOOL_THREADS, 2 * ideal_th_count));
|
m_workHorsePool->setMaxThreadCount((std::min)(MAX_THREADPOOL_THREADS, 2 * ideal_th_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION_MAJOR == 6
|
||||||
|
// Avoid competing with interactive processes/threads by running the
|
||||||
|
// worker pool at a very low priority
|
||||||
|
m_workHorsePool->setThreadPriority(QThread::LowestPriority);
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOTE: Do not expire threads so that their IDs are not reused.
|
// NOTE: Do not expire threads so that their IDs are not reused.
|
||||||
// This fixes cross-thread QSqlDatabase access.
|
// This fixes cross-thread QSqlDatabase access.
|
||||||
m_workHorsePool->setExpiryTimeout(-1);
|
m_workHorsePool->setExpiryTimeout(-1);
|
||||||
|
@ -128,7 +128,7 @@ void FeedReader::initializeFeedDownloader() {
|
|||||||
connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted);
|
connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted);
|
||||||
connect(m_feedDownloader, &FeedDownloader::updateFinished, qApp->feedUpdateLock(), &Mutex::unlock);
|
connect(m_feedDownloader, &FeedDownloader::updateFinished, qApp->feedUpdateLock(), &Mutex::unlock);
|
||||||
|
|
||||||
m_feedDownloaderThread->start();
|
m_feedDownloaderThread->start(QThread::LowPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
67
src/librssguard/miscellaneous/thread.cpp
Normal file
67
src/librssguard/miscellaneous/thread.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||||
|
|
||||||
|
#include "definitions/definitions.h"
|
||||||
|
#include "miscellaneous/thread.h"
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Returns the thread ID of the caller
|
||||||
|
qlonglong getThreadID() {
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
return qlonglong(gettid());
|
||||||
|
#else
|
||||||
|
return qlonglong(QThread::currentThreadId());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
// On Linux QThread priorities do nothing with the default scheduler SCHED_OTHER
|
||||||
|
// Set the nice value manually in this case until Qt supports nice values
|
||||||
|
void setThreadPriority(Priority prio) {
|
||||||
|
int current_policy = sched_getscheduler(0);
|
||||||
|
if (current_policy != -1) {
|
||||||
|
// If the current scheduling policy is neither of these the QThread priority should be working
|
||||||
|
if (current_policy != SCHED_BATCH && current_policy != SCHED_OTHER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the scheduler to SCHED_BATCH if needed, indicating that this process is non-interactive
|
||||||
|
if (current_policy == SCHED_OTHER) {
|
||||||
|
struct sched_param p = {0};
|
||||||
|
if (sched_setscheduler(0, SCHED_BATCH, &p) != 0) {
|
||||||
|
qDebugNN << "Setting the scheduler to SCHED_BATCH for thread"
|
||||||
|
<< QUOTE_W_SPACE(getThreadID())
|
||||||
|
<< "failed with error" << QUOTE_W_SPACE_DOT(errno);
|
||||||
|
// We can still try to set the nice value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0; // Clear errno since -1 is a legitimate return value
|
||||||
|
int current_priority = getpriority(PRIO_PROCESS, 0);
|
||||||
|
if (errno != 0) {
|
||||||
|
qDebugNN << "Getting the priority for thread"
|
||||||
|
<< QUOTE_W_SPACE(getThreadID())
|
||||||
|
<< "failed with error" << QUOTE_W_SPACE_DOT(errno);
|
||||||
|
} else {
|
||||||
|
if (current_priority != prio) {
|
||||||
|
setpriority(PRIO_PROCESS, 0, prio);
|
||||||
|
if (errno != 0) {
|
||||||
|
qDebugNN << "Setting the priority for thread"
|
||||||
|
<< QUOTE_W_SPACE(getThreadID())
|
||||||
|
<< "failed with error" << QUOTE_W_SPACE_DOT(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qDebugNN << "Getting the priority for thread"
|
||||||
|
<< QUOTE_W_SPACE(getThreadID())
|
||||||
|
<< "failed with error" << QUOTE_W_SPACE_DOT(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
19
src/librssguard/miscellaneous/thread.h
Normal file
19
src/librssguard/miscellaneous/thread.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||||
|
|
||||||
|
#ifndef THREAD_H
|
||||||
|
#define THREAD_H
|
||||||
|
|
||||||
|
qlonglong getThreadID();
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
// Values corresponding to nice values
|
||||||
|
enum Priority {
|
||||||
|
LOWEST = 19,
|
||||||
|
LOW = 10,
|
||||||
|
NORMAL = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
void setThreadPriority(Priority);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // THREAD_H
|
@ -23,7 +23,6 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QThread>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user