diff --git a/src/core/feeddownloader.cpp b/src/core/feeddownloader.cpp index c2f23d304..60834c213 100755 --- a/src/core/feeddownloader.cpp +++ b/src/core/feeddownloader.cpp @@ -26,61 +26,81 @@ FeedDownloader::FeedDownloader(QObject *parent) - : QObject(parent), m_threadPool(new QThreadPool(this)), m_results(FeedDownloadResults()), m_feedsUpdated(0), m_feedsToUpdate(0), - m_feedsUpdating(0), m_feedsTotalCount(0), m_stopUpdate(false) { + : QObject(parent), m_feeds(QList()), m_mutex(new QMutex()), m_threadPool(new QThreadPool(this)), + m_results(FeedDownloadResults()), m_feedsUpdated(0), + m_feedsUpdating(0), m_feedsTotalCount(0) { qRegisterMetaType("FeedDownloadResults"); - m_threadPool->setMaxThreadCount(FEED_DOWNLOADER_MAX_THREADS); } FeedDownloader::~FeedDownloader() { + m_mutex->tryLock(); + m_mutex->unlock(); + delete m_mutex; + qDebug("Destroying FeedDownloader instance."); } bool FeedDownloader::isUpdateRunning() const { - return m_feedsToUpdate > 0 || m_feedsUpdating > 0; + QMutexLocker locker(m_mutex); + + return !m_feeds.isEmpty() || m_feedsUpdating > 0; +} + +void FeedDownloader::updateAvailableFeeds() { + while (!m_feeds.isEmpty()) { + connect(m_feeds.first(), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished, + (Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection)); + if (m_threadPool->tryStart(m_feeds.first())) { + m_feeds.removeFirst(); + m_feedsUpdating++; + } + else { + // We want to start update of some feeds but all working threads are occupied. + break; + } + } } void FeedDownloader::updateFeeds(const QList &feeds) { + QMutexLocker locker(m_mutex); + if (feeds.isEmpty()) { qDebug("No feeds to update in worker thread, aborting update."); finalizeUpdate(); - return; } + else { + qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'."; - qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'."; + m_feeds = feeds; + m_results.clear(); + m_feedsUpdated = m_feedsUpdating = 0; - m_results.clear(); - - m_feedsUpdated = 0; - m_feedsUpdating = 0; - m_feedsToUpdate = feeds.size(); - m_feedsTotalCount = m_feedsToUpdate; - - // Job starts now. - emit updateStarted(); - - for (int i = 0; i < m_feedsTotalCount; i++) { - connect(feeds.at(i), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished, - (Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection)); - m_threadPool->start(feeds.at(i)); - - m_feedsUpdating++; - m_feedsToUpdate--; + // Job starts now. + emit updateStarted(); + updateAvailableFeeds(); } } void FeedDownloader::stopRunningUpdate() { + //QMutexLocker locker(m_mutex); + m_threadPool->clear(); + m_feeds.clear(); } void FeedDownloader::oneFeedUpdateFinished(const QList &messages) { + QMutexLocker locker(m_mutex); + + m_feedsUpdated++; + m_feedsUpdating--; + Feed *feed = qobject_cast(sender()); disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished); - m_feedsUpdated++; - m_feedsUpdating--; + // Now, we check if there are any feeds we would like to update too. + updateAvailableFeeds(); // Now make sure, that messages are actually stored to SQL in a locked state. qDebug().nospace() << "Saving messages of feed " @@ -100,7 +120,7 @@ void FeedDownloader::oneFeedUpdateFinished(const QList &messages) { qDebug("Made progress in feed updates, total feeds count %d/%d (id of feed is %d).", m_feedsUpdated, m_feedsTotalCount, feed->id()); emit updateProgress(feed, m_feedsUpdated, m_feedsTotalCount); - if (m_threadPool->activeThreadCount() <= 0 || (m_feedsToUpdate <= 0 && m_feedsUpdating <= 0)) { + if (m_feeds.isEmpty() && m_feedsUpdating <= 0) { finalizeUpdate(); } } @@ -108,9 +128,6 @@ void FeedDownloader::oneFeedUpdateFinished(const QList &messages) { void FeedDownloader::finalizeUpdate() { qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'."; - m_feedsToUpdate = 0; - m_feedsUpdating = 0; - m_results.sort(); // Update of feeds has finished. diff --git a/src/core/feeddownloader.h b/src/core/feeddownloader.h index d4741a215..02683b28b 100755 --- a/src/core/feeddownloader.h +++ b/src/core/feeddownloader.h @@ -87,17 +87,17 @@ class FeedDownloader : public QObject { void updateProgress(const Feed *feed, int current, int total); private: + void updateAvailableFeeds(); void finalizeUpdate(); + QList m_feeds; + QMutex *m_mutex; QThreadPool *m_threadPool; FeedDownloadResults m_results; int m_feedsUpdated; - int m_feedsToUpdate; int m_feedsUpdating; int m_feedsTotalCount; - - bool m_stopUpdate; }; #endif // FEEDDOWNLOADER_H diff --git a/src/miscellaneous/feedreader.cpp b/src/miscellaneous/feedreader.cpp index 021a2ed37..91e063af9 100755 --- a/src/miscellaneous/feedreader.cpp +++ b/src/miscellaneous/feedreader.cpp @@ -84,9 +84,7 @@ void FeedReader::updateFeeds(const QList &feeds) { qRegisterMetaType >("QList"); m_feedDownloader->moveToThread(m_feedDownloaderThread); - connect(this, &FeedReader::feedsUpdateRequested, m_feedDownloader, &FeedDownloader::updateFeeds); connect(m_feedDownloaderThread, &QThread::finished, m_feedDownloaderThread, &QThread::deleteLater); - connect(m_feedDownloader, &FeedDownloader::updateFinished, this, &FeedReader::feedUpdatesFinished); connect(m_feedDownloader, &FeedDownloader::updateProgress, this, &FeedReader::feedUpdatesProgress); connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted); @@ -96,7 +94,7 @@ void FeedReader::updateFeeds(const QList &feeds) { m_feedDownloaderThread->start(); } - emit feedsUpdateRequested(feeds); + QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds", Q_ARG(QList, feeds)); } void FeedReader::updateAutoUpdateStatus() { @@ -126,7 +124,7 @@ void FeedReader::updateAllFeeds() { void FeedReader::stopRunningFeedUpdate() { if (m_feedDownloader != nullptr) { - m_feedDownloader->stopRunningUpdate(); + QMetaObject::invokeMethod(m_feedDownloader, "stopRunningUpdate"); } } diff --git a/src/miscellaneous/feedreader.h b/src/miscellaneous/feedreader.h index a1a994bc4..a31c17e7c 100755 --- a/src/miscellaneous/feedreader.h +++ b/src/miscellaneous/feedreader.h @@ -72,9 +72,6 @@ class FeedReader : public QObject { void executeNextAutoUpdate(); signals: - // Emitted when model requests update of some feeds. - void feedsUpdateRequested(QList feeds); - void feedUpdatesStarted(); void feedUpdatesFinished(FeedDownloadResults updated_feeds); void feedUpdatesProgress(const Feed *feed, int current, int total);