From 7e14390e2c3c743fa7b53b2d7edd1d01884c38c3 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 5 Jan 2023 09:44:46 +0100 Subject: [PATCH] make cookie jar thread safe, make qsettings thread safe --- resources/desktop/rssguard.metainfo.xml.in | 2 +- src/librssguard/core/feeddownloader.cpp | 29 ++++++---------------- src/librssguard/miscellaneous/settings.cpp | 3 ++- src/librssguard/miscellaneous/settings.h | 9 ++++++- src/librssguard/network-web/cookiejar.cpp | 11 ++++++++ src/librssguard/network-web/cookiejar.h | 4 +++ 6 files changed, 33 insertions(+), 25 deletions(-) diff --git a/resources/desktop/rssguard.metainfo.xml.in b/resources/desktop/rssguard.metainfo.xml.in index 8f3f27b2c..5da01b359 100644 --- a/resources/desktop/rssguard.metainfo.xml.in +++ b/resources/desktop/rssguard.metainfo.xml.in @@ -60,7 +60,7 @@ - + @APP_LOW_NAME@ diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index ec512e8f0..77cc6c82c 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -82,23 +82,14 @@ void FeedDownloader::updateFeeds(const QList& feeds) { qDebugNN << LOGSEC_FEEDDOWNLOADER << "No feeds to update in worker thread, aborting update."; } else { - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Starting feed updates from worker in thread: '" << QThread::currentThreadId() - << "'."; + qDebugNN << LOGSEC_FEEDDOWNLOADER << "Starting feed updates from worker in thread" + << QUOTE_W_SPACE_DOT(QThread::currentThreadId()); // Job starts now. emit updateStarted(); QSet caches; QMultiHash feeds_per_root; - // 1. key - account. - // 2. key - feed custom ID. - // 3. key - msg state. - QHash>> stated_messages; - - // 1. key - account. - // 2. key - label custom ID. - QHash> tagged_messages; - for (auto* fd : feeds) { CacheForServiceRoot* fd_cache = fd->getParentServiceRoot()->toCache(); @@ -112,21 +103,17 @@ void FeedDownloader::updateFeeds(const QList& feeds) { synchronizeAccountCaches(caches.values(), false); auto roots = feeds_per_root.uniqueKeys(); - bool is_main_thread = QThread::currentThread() == qApp->thread(); - QSqlDatabase database = is_main_thread ? qApp->database()->driver()->connection(metaObject()->className()) - : qApp->database()->driver()->connection(QSL("feed_upd")); + QSqlDatabase database = qApp->database()->driver()->threadSafeConnection(metaObject()->className()); for (auto* rt : roots) { auto fds = feeds_per_root.values(rt); + QHash per_acc_tags; + QHash> per_acc_states; // Obtain lists of local IDs. if (rt->wantsBaggedIdsOfExistingMessages()) { // Tags per account. - auto per_acc_tags = DatabaseQueries::bagsOfMessages(database, rt->labelsNode()->labels()); - - tagged_messages.insert(rt, per_acc_tags); - - QHash> per_acc_states; + per_acc_tags = DatabaseQueries::bagsOfMessages(database, rt->labelsNode()->labels()); // This account has activated intelligent downloading of messages. // Prepare bags. @@ -151,8 +138,6 @@ void FeedDownloader::updateFeeds(const QList& feeds) { m_feeds.append(fu); } - - stated_messages.insert(rt, per_acc_states); } else { for (Feed* fd : fds) { @@ -166,7 +151,7 @@ void FeedDownloader::updateFeeds(const QList& feeds) { } try { - rt->aboutToBeginFeedFetching(fds, stated_messages.value(rt), tagged_messages.value(rt)); + rt->aboutToBeginFeedFetching(fds, per_acc_states, per_acc_tags); } catch (const ApplicationException& ex) { // Common error showed, all feeds from the root are errored now! diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp index 9edb1e1e8..ea135a409 100644 --- a/src/librssguard/miscellaneous/settings.cpp +++ b/src/librssguard/miscellaneous/settings.cpp @@ -438,7 +438,8 @@ DVALUE(QStringList) Browser::ExternalToolsDef = QStringList(); DKEY CategoriesExpandStates::ID = "categories_expand_states"; Settings::Settings(const QString& file_name, Format format, SettingsProperties::SettingsType type, QObject* parent) - : QSettings(file_name, format, parent), m_initializationStatus(type) { + : QSettings(file_name, format, parent), m_lock(QReadWriteLock(QReadWriteLock::RecursionMode::Recursive)), + m_initializationStatus(type) { Messages::PreviewerFontStandardDef = QFont(QApplication::font().family(), 12).toString(); } diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h index cfbd56591..f8d25f301 100644 --- a/src/librssguard/miscellaneous/settings.h +++ b/src/librssguard/miscellaneous/settings.h @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include #define KEY extern const QString #define DKEY const QString @@ -518,12 +520,13 @@ class Settings : public QSettings { static SettingsProperties determineProperties(); private: - // Constructor. explicit Settings(const QString& file_name, Format format, SettingsProperties::SettingsType type, QObject* parent = nullptr); + private: + mutable QReadWriteLock m_lock; SettingsProperties::SettingsType m_initializationStatus; }; @@ -545,10 +548,12 @@ inline QVariant Settings::value(const QString& section, const QString& key, cons } inline void Settings::setValue(const QString& section, const QString& key, const QVariant& value) { + QWriteLocker lck(&m_lock); QSettings::setValue(QString(QSL("%1/%2")).arg(section, key), value); } inline void Settings::setValue(const QString& key, const QVariant& value) { + QWriteLocker lck(&m_lock); QSettings::setValue(key, value); } @@ -557,6 +562,8 @@ inline bool Settings::contains(const QString& section, const QString& key) const } inline void Settings::remove(const QString& section, const QString& key) { + QWriteLocker lck(&m_lock); + if (key.isEmpty()) { beginGroup(section); QSettings::remove({}); diff --git a/src/librssguard/network-web/cookiejar.cpp b/src/librssguard/network-web/cookiejar.cpp index b819f7bae..fd0414b25 100644 --- a/src/librssguard/network-web/cookiejar.cpp +++ b/src/librssguard/network-web/cookiejar.cpp @@ -120,10 +120,12 @@ void CookieJar::saveCookies() { } QList CookieJar::cookiesForUrl(const QUrl& url) const { + QReadLocker l(&m_lock); return QNetworkCookieJar::cookiesForUrl(url); } bool CookieJar::setCookiesFromUrl(const QList& cookie_list, const QUrl& url) { + QWriteLocker l(&m_lock); return QNetworkCookieJar::setCookiesFromUrl(cookie_list, url); } @@ -188,11 +190,13 @@ bool CookieJar::insertCookie(const QNetworkCookie& cookie) { return {}; } else { + QWriteLocker l(&m_lock); return insertCookieInternal(cookie, false, true); } } bool CookieJar::deleteCookie(const QNetworkCookie& cookie) { + QWriteLocker l(&m_lock); return deleteCookieInternal(cookie, false); } @@ -206,5 +210,12 @@ void CookieJar::updateSettings() { } bool CookieJar::updateCookie(const QNetworkCookie& cookie) { + QWriteLocker l(&m_lock); return updateCookieInternal(cookie, false); } + +/* +bool CookieJar::validateCookie(const QNetworkCookie &cookie, const QUrl &url) const { + return QNetworkCookieJar::validateCookie(cookie, url); +} +*/ diff --git a/src/librssguard/network-web/cookiejar.h b/src/librssguard/network-web/cookiejar.h index 59f97e4ad..5409685f5 100644 --- a/src/librssguard/network-web/cookiejar.h +++ b/src/librssguard/network-web/cookiejar.h @@ -5,6 +5,8 @@ #include +#include + #if defined(USE_WEBENGINE) class QWebEngineCookieStore; #endif @@ -18,6 +20,7 @@ class CookieJar : public QNetworkCookieJar { virtual bool insertCookie(const QNetworkCookie& cookie); virtual bool updateCookie(const QNetworkCookie& cookie); virtual bool deleteCookie(const QNetworkCookie& cookie); + // virtual bool validateCookie(const QNetworkCookie& cookie, const QUrl& url) const; void updateSettings(); @@ -37,6 +40,7 @@ class CookieJar : public QNetworkCookieJar { QWebEngineCookieStore* m_webEngineCookies; #endif + mutable QReadWriteLock m_lock{QReadWriteLock::RecursionMode::Recursive}; bool m_ignoreAllCookies; };