make cookie jar thread safe, make qsettings thread safe
This commit is contained in:
parent
e87ecd91f2
commit
7e14390e2c
6 changed files with 33 additions and 25 deletions
|
@ -60,7 +60,7 @@
|
||||||
<content_rating type="oars-1.0" />
|
<content_rating type="oars-1.0" />
|
||||||
<content_rating type="oars-1.1" />
|
<content_rating type="oars-1.1" />
|
||||||
<releases>
|
<releases>
|
||||||
<release version="4.2.7" date="2023-01-04" />
|
<release version="4.2.7" date="2023-01-05" />
|
||||||
</releases>
|
</releases>
|
||||||
<provides>
|
<provides>
|
||||||
<binary>@APP_LOW_NAME@</binary>
|
<binary>@APP_LOW_NAME@</binary>
|
||||||
|
|
|
@ -82,23 +82,14 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << "No feeds to update in worker thread, aborting update.";
|
qDebugNN << LOGSEC_FEEDDOWNLOADER << "No feeds to update in worker thread, aborting update.";
|
||||||
}
|
}
|
||||||
else {
|
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.
|
// Job starts now.
|
||||||
emit updateStarted();
|
emit updateStarted();
|
||||||
QSet<CacheForServiceRoot*> caches;
|
QSet<CacheForServiceRoot*> caches;
|
||||||
QMultiHash<ServiceRoot*, Feed*> feeds_per_root;
|
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) {
|
for (auto* fd : feeds) {
|
||||||
CacheForServiceRoot* fd_cache = fd->getParentServiceRoot()->toCache();
|
CacheForServiceRoot* fd_cache = fd->getParentServiceRoot()->toCache();
|
||||||
|
|
||||||
|
@ -112,21 +103,17 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
||||||
synchronizeAccountCaches(caches.values(), false);
|
synchronizeAccountCaches(caches.values(), false);
|
||||||
|
|
||||||
auto roots = feeds_per_root.uniqueKeys();
|
auto roots = feeds_per_root.uniqueKeys();
|
||||||
bool is_main_thread = QThread::currentThread() == qApp->thread();
|
QSqlDatabase database = qApp->database()->driver()->threadSafeConnection(metaObject()->className());
|
||||||
QSqlDatabase database = is_main_thread ? qApp->database()->driver()->connection(metaObject()->className())
|
|
||||||
: qApp->database()->driver()->connection(QSL("feed_upd"));
|
|
||||||
|
|
||||||
for (auto* rt : roots) {
|
for (auto* rt : roots) {
|
||||||
auto fds = feeds_per_root.values(rt);
|
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.
|
// Obtain lists of local IDs.
|
||||||
if (rt->wantsBaggedIdsOfExistingMessages()) {
|
if (rt->wantsBaggedIdsOfExistingMessages()) {
|
||||||
// Tags per account.
|
// Tags per account.
|
||||||
auto per_acc_tags = DatabaseQueries::bagsOfMessages(database, rt->labelsNode()->labels());
|
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;
|
|
||||||
|
|
||||||
// This account has activated intelligent downloading of messages.
|
// This account has activated intelligent downloading of messages.
|
||||||
// Prepare bags.
|
// Prepare bags.
|
||||||
|
@ -151,8 +138,6 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
||||||
|
|
||||||
m_feeds.append(fu);
|
m_feeds.append(fu);
|
||||||
}
|
}
|
||||||
|
|
||||||
stated_messages.insert(rt, per_acc_states);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (Feed* fd : fds) {
|
for (Feed* fd : fds) {
|
||||||
|
@ -166,7 +151,7 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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) {
|
catch (const ApplicationException& ex) {
|
||||||
// Common error showed, all feeds from the root are errored now!
|
// Common error showed, all feeds from the root are errored now!
|
||||||
|
|
|
@ -438,7 +438,8 @@ DVALUE(QStringList) Browser::ExternalToolsDef = QStringList();
|
||||||
DKEY CategoriesExpandStates::ID = "categories_expand_states";
|
DKEY CategoriesExpandStates::ID = "categories_expand_states";
|
||||||
|
|
||||||
Settings::Settings(const QString& file_name, Format format, SettingsProperties::SettingsType type, QObject* parent)
|
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();
|
Messages::PreviewerFontStandardDef = QFont(QApplication::font().family(), 12).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
|
#include <QReadWriteLock>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QWriteLocker>
|
||||||
|
|
||||||
#define KEY extern const QString
|
#define KEY extern const QString
|
||||||
#define DKEY const QString
|
#define DKEY const QString
|
||||||
|
@ -518,12 +520,13 @@ class Settings : public QSettings {
|
||||||
static SettingsProperties determineProperties();
|
static SettingsProperties determineProperties();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Constructor.
|
|
||||||
explicit Settings(const QString& file_name,
|
explicit Settings(const QString& file_name,
|
||||||
Format format,
|
Format format,
|
||||||
SettingsProperties::SettingsType type,
|
SettingsProperties::SettingsType type,
|
||||||
QObject* parent = nullptr);
|
QObject* parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable QReadWriteLock m_lock;
|
||||||
SettingsProperties::SettingsType m_initializationStatus;
|
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) {
|
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);
|
QSettings::setValue(QString(QSL("%1/%2")).arg(section, key), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Settings::setValue(const QString& key, const QVariant& value) {
|
inline void Settings::setValue(const QString& key, const QVariant& value) {
|
||||||
|
QWriteLocker lck(&m_lock);
|
||||||
QSettings::setValue(key, value);
|
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) {
|
inline void Settings::remove(const QString& section, const QString& key) {
|
||||||
|
QWriteLocker lck(&m_lock);
|
||||||
|
|
||||||
if (key.isEmpty()) {
|
if (key.isEmpty()) {
|
||||||
beginGroup(section);
|
beginGroup(section);
|
||||||
QSettings::remove({});
|
QSettings::remove({});
|
||||||
|
|
|
@ -120,10 +120,12 @@ void CookieJar::saveCookies() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl& url) const {
|
QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl& url) const {
|
||||||
|
QReadLocker l(&m_lock);
|
||||||
return QNetworkCookieJar::cookiesForUrl(url);
|
return QNetworkCookieJar::cookiesForUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie>& cookie_list, const QUrl& url) {
|
bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie>& cookie_list, const QUrl& url) {
|
||||||
|
QWriteLocker l(&m_lock);
|
||||||
return QNetworkCookieJar::setCookiesFromUrl(cookie_list, url);
|
return QNetworkCookieJar::setCookiesFromUrl(cookie_list, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,11 +190,13 @@ bool CookieJar::insertCookie(const QNetworkCookie& cookie) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
QWriteLocker l(&m_lock);
|
||||||
return insertCookieInternal(cookie, false, true);
|
return insertCookieInternal(cookie, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieJar::deleteCookie(const QNetworkCookie& cookie) {
|
bool CookieJar::deleteCookie(const QNetworkCookie& cookie) {
|
||||||
|
QWriteLocker l(&m_lock);
|
||||||
return deleteCookieInternal(cookie, false);
|
return deleteCookieInternal(cookie, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,5 +210,12 @@ void CookieJar::updateSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieJar::updateCookie(const QNetworkCookie& cookie) {
|
bool CookieJar::updateCookie(const QNetworkCookie& cookie) {
|
||||||
|
QWriteLocker l(&m_lock);
|
||||||
return updateCookieInternal(cookie, false);
|
return updateCookieInternal(cookie, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool CookieJar::validateCookie(const QNetworkCookie &cookie, const QUrl &url) const {
|
||||||
|
return QNetworkCookieJar::validateCookie(cookie, url);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <QNetworkCookieJar>
|
#include <QNetworkCookieJar>
|
||||||
|
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
|
||||||
#if defined(USE_WEBENGINE)
|
#if defined(USE_WEBENGINE)
|
||||||
class QWebEngineCookieStore;
|
class QWebEngineCookieStore;
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +20,7 @@ class CookieJar : public QNetworkCookieJar {
|
||||||
virtual bool insertCookie(const QNetworkCookie& cookie);
|
virtual bool insertCookie(const QNetworkCookie& cookie);
|
||||||
virtual bool updateCookie(const QNetworkCookie& cookie);
|
virtual bool updateCookie(const QNetworkCookie& cookie);
|
||||||
virtual bool deleteCookie(const QNetworkCookie& cookie);
|
virtual bool deleteCookie(const QNetworkCookie& cookie);
|
||||||
|
// virtual bool validateCookie(const QNetworkCookie& cookie, const QUrl& url) const;
|
||||||
|
|
||||||
void updateSettings();
|
void updateSettings();
|
||||||
|
|
||||||
|
@ -37,6 +40,7 @@ class CookieJar : public QNetworkCookieJar {
|
||||||
QWebEngineCookieStore* m_webEngineCookies;
|
QWebEngineCookieStore* m_webEngineCookies;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mutable QReadWriteLock m_lock{QReadWriteLock::RecursionMode::Recursive};
|
||||||
bool m_ignoreAllCookies;
|
bool m_ignoreAllCookies;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue