make cookie jar thread safe, make qsettings thread safe

This commit is contained in:
Martin Rotter 2023-01-05 09:44:46 +01:00
parent e87ecd91f2
commit 7e14390e2c
6 changed files with 33 additions and 25 deletions

View File

@ -60,7 +60,7 @@
<content_rating type="oars-1.0" />
<content_rating type="oars-1.1" />
<releases>
<release version="4.2.7" date="2023-01-04" />
<release version="4.2.7" date="2023-01-05" />
</releases>
<provides>
<binary>@APP_LOW_NAME@</binary>

View File

@ -82,23 +82,14 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& 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<CacheForServiceRoot*> caches;
QMultiHash<ServiceRoot*, Feed*> feeds_per_root;
// 1. key - account.
// 2. key - feed custom ID.
// 3. key - msg state.
QHash<ServiceRoot*, QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>> stated_messages;
// 1. key - account.
// 2. key - label custom ID.
QHash<ServiceRoot*, QHash<QString, QStringList>> tagged_messages;
for (auto* fd : feeds) {
CacheForServiceRoot* fd_cache = fd->getParentServiceRoot()->toCache();
@ -112,21 +103,17 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& 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<QString, QStringList> per_acc_tags;
QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>> 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<QString, QHash<ServiceRoot::BagOfMessages, QStringList>> 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<Feed*>& 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<Feed*>& 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!

View File

@ -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();
}

View File

@ -14,7 +14,9 @@
#include <QColor>
#include <QDateTime>
#include <QNetworkProxy>
#include <QReadWriteLock>
#include <QStringList>
#include <QWriteLocker>
#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({});

View File

@ -120,10 +120,12 @@ void CookieJar::saveCookies() {
}
QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl& url) const {
QReadLocker l(&m_lock);
return QNetworkCookieJar::cookiesForUrl(url);
}
bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie>& 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);
}
*/

View File

@ -5,6 +5,8 @@
#include <QNetworkCookieJar>
#include <QReadWriteLock>
#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;
};