From 54e883c32246f1fc2c6170b73ac41fd99f92bef0 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Sun, 16 Nov 2014 00:43:08 +0000 Subject: [PATCH] refs #334 VATSIM threaded reader classes using CContinuousWorker. --- src/blackcore/context_network_impl.cpp | 10 +++--- src/blackcore/vatsimbookingreader.cpp | 10 +++--- src/blackcore/vatsimbookingreader.h | 4 +-- src/blackcore/vatsimdatafilereader.cpp | 10 +++--- src/blackcore/vatsimdatafilereader.h | 4 +-- src/blackmisc/threadedreader.h | 45 ++++---------------------- 6 files changed, 27 insertions(+), 56 deletions(-) diff --git a/src/blackcore/context_network_impl.cpp b/src/blackcore/context_network_impl.cpp index 4feac9eb2..2bf03a2d4 100644 --- a/src/blackcore/context_network_impl.cpp +++ b/src/blackcore/context_network_impl.cpp @@ -50,17 +50,19 @@ namespace BlackCore connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::ps_fsdTextMessageReceived); // 2. VATSIM bookings - this->m_vatsimBookingReader = new CVatsimBookingReader(this->getRuntime()->getIContextSettings()->getNetworkSettings().getBookingServiceUrl(), this); + this->m_vatsimBookingReader = new CVatsimBookingReader(this, this->getRuntime()->getIContextSettings()->getNetworkSettings().getBookingServiceUrl()); connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CContextNetwork::ps_receivedBookings); this->m_vatsimBookingReader->read(); // first read this->m_vatsimBookingReader->setInterval(180 * 1000); + this->m_vatsimBookingReader->start(); // 3. VATSIM data file const QStringList dataFileUrls = { "http://info.vroute.net/vatsim-data.txt" }; - this->m_vatsimDataFileReader = new CVatsimDataFileReader(dataFileUrls, this); + this->m_vatsimDataFileReader = new CVatsimDataFileReader(this, dataFileUrls); connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CContextNetwork::ps_dataFileRead); this->m_vatsimDataFileReader->read(); // first read this->m_vatsimDataFileReader->setInterval(90 * 1000); + this->m_vatsimDataFileReader->start(); // 4. Update timer for data (network data such as frequency) this->m_dataUpdateTimer = new QTimer(this); @@ -91,8 +93,8 @@ namespace BlackCore */ void CContextNetwork::gracefulShutdown() { - if (this->m_vatsimBookingReader) this->m_vatsimBookingReader->stop(); - if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->stop(); + if (this->m_vatsimBookingReader) this->m_vatsimBookingReader->quit(); + if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->quit(); if (this->isConnected()) this->disconnectFromNetwork(); } diff --git a/src/blackcore/vatsimbookingreader.cpp b/src/blackcore/vatsimbookingreader.cpp index 52e17dc8d..5f7412854 100644 --- a/src/blackcore/vatsimbookingreader.cpp +++ b/src/blackcore/vatsimbookingreader.cpp @@ -22,8 +22,8 @@ using namespace BlackMisc::Network; namespace BlackCore { - CVatsimBookingReader::CVatsimBookingReader(const QString &url, QObject *parent) : - QObject(parent), CThreadedReader(), + CVatsimBookingReader::CVatsimBookingReader(QObject *owner, const QString &url) : + CThreadedReader(owner), m_serviceUrl(url), m_networkManager(nullptr) { this->m_networkManager = new QNetworkAccessManager(this); @@ -47,7 +47,7 @@ namespace BlackCore void CVatsimBookingReader::ps_loadFinished(QNetworkReply *nwReply) { this->setPendingNetworkReply(nullptr); - if (!this->isStopped()) + if (!this->isFinished()) { QFuture f = QtConcurrent::run(this, &CVatsimBookingReader::parseBookings, nwReply); this->setPendingFuture(f); @@ -64,7 +64,7 @@ namespace BlackCore QScopedPointer nwReply(nwReplyPtr); // Worker thread, make sure to write no members here! - if (this->isStopped()) + if (this->isFinished()) { CLogMessage(this).debug() << Q_FUNC_INFO; CLogMessage(this).info("terminated booking parsing process"); // for users @@ -100,7 +100,7 @@ namespace BlackCore CAtcStationList bookedStations; for (int i = 0; i < size; i++) { - if (this->isStopped()) + if (this->isFinished()) { CLogMessage(this).debug() << Q_FUNC_INFO; CLogMessage(this).info("terminated booking parsing process"); // for users diff --git a/src/blackcore/vatsimbookingreader.h b/src/blackcore/vatsimbookingreader.h index 18d035f28..ab2dc7a46 100644 --- a/src/blackcore/vatsimbookingreader.h +++ b/src/blackcore/vatsimbookingreader.h @@ -25,13 +25,13 @@ namespace BlackCore /*! * Read bookings from VATSIM */ - class CVatsimBookingReader : public QObject, public BlackMisc::CThreadedReader + class CVatsimBookingReader : public BlackMisc::CThreadedReader { Q_OBJECT public: //! Constructor - explicit CVatsimBookingReader(const QString &url, QObject *parent = nullptr); + explicit CVatsimBookingReader(QObject *owner, const QString &url); //! Read / re-read bookings void read(); diff --git a/src/blackcore/vatsimdatafilereader.cpp b/src/blackcore/vatsimdatafilereader.cpp index 18af32c49..2a6125a8f 100644 --- a/src/blackcore/vatsimdatafilereader.cpp +++ b/src/blackcore/vatsimdatafilereader.cpp @@ -25,8 +25,8 @@ using namespace BlackMisc::PhysicalQuantities; namespace BlackCore { - CVatsimDataFileReader::CVatsimDataFileReader(const QStringList &urls, QObject *parent) : - QObject(parent), CThreadedReader(), + CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner, const QStringList &urls) : + CThreadedReader(owner), m_serviceUrls(urls), m_currentUrlIndex(0), m_networkManager(nullptr) { this->m_networkManager = new QNetworkAccessManager(this); @@ -149,7 +149,7 @@ namespace BlackCore void CVatsimDataFileReader::ps_loadFinished(QNetworkReply *nwReply) { this->setPendingNetworkReply(nullptr); - if (!this->isStopped()) + if (!this->isFinished()) { QFuture f = QtConcurrent::run(this, &CVatsimDataFileReader::parseVatsimFileInBackground, nwReply); this->setPendingFuture(f); @@ -167,7 +167,7 @@ namespace BlackCore QScopedPointer nwReply(nwReplyPtr); // Worker thread, make sure to write only synced here! - if (this->isStopped()) + if (this->isFinished()) { CLogMessage(this).debug() << Q_FUNC_INFO; CLogMessage(this).info("terminated VATSIM file parsing process"); // for users @@ -196,7 +196,7 @@ namespace BlackCore Section section = SectionNone; foreach(QString currentLine, lines) { - if (this->isStopped()) + if (this->isFinished()) { CLogMessage(this).debug() << Q_FUNC_INFO; CLogMessage(this).info("terminated booking parsing process"); // for users diff --git a/src/blackcore/vatsimdatafilereader.h b/src/blackcore/vatsimdatafilereader.h index c1c2a8e9f..e9c347bd2 100644 --- a/src/blackcore/vatsimdatafilereader.h +++ b/src/blackcore/vatsimdatafilereader.h @@ -30,13 +30,13 @@ namespace BlackCore /*! * Read bookings from VATSIM */ - class CVatsimDataFileReader : public QObject, public BlackMisc::CThreadedReader + class CVatsimDataFileReader : public BlackMisc::CThreadedReader { Q_OBJECT public: //! Constructor - explicit CVatsimDataFileReader(const QStringList &urls, QObject *parent = nullptr); + explicit CVatsimDataFileReader(QObject *owner, const QStringList &urls); //! Read / re-read data file void read(); diff --git a/src/blackmisc/threadedreader.h b/src/blackmisc/threadedreader.h index 767cdc55d..54cf78306 100644 --- a/src/blackmisc/threadedreader.h +++ b/src/blackmisc/threadedreader.h @@ -12,6 +12,7 @@ //! \file +#include "worker.h" #include #include #include @@ -27,17 +28,9 @@ namespace BlackMisc * * \remarks Header only class to avoid forward instantiations across subprojects */ - template class CThreadedReader + template class CThreadedReader : public CContinuousWorker { - public: - //! Destructor - virtual ~CThreadedReader() - { - this->stop(); - delete m_updateTimer; - } - //! Thread safe, set update timestamp //! \threadsafe QDateTime getUpdateTimestamp() const @@ -54,16 +47,9 @@ namespace BlackMisc this->m_updateTimestamp = updateTimestamp; } - //! Thread safe, mark as stopped - //! \threadsafe - virtual void stop() + //! \copydoc CContinuousWorker::cleanup + virtual void cleanup() override { - if (this->isStopped()) return; - - // thread safe stopping timer and mark as stopped - this->setStopFlag(); - this->setInterval(0); - // shutdown pending QWriteLocker(&this->m_lock); if (this->m_pendingFuture.isRunning()) @@ -76,21 +62,12 @@ namespace BlackMisc if (this->m_pendingNetworkReply && this->m_pendingNetworkReply->isRunning()) { this->m_pendingNetworkReply->abort(); - QCoreApplication::processEvents(QEventLoop::AllEvents, 250); // allow the abort to be called } // cancel or stop flag above should terminate QFuture this->m_pendingFuture.waitForFinished(); } - //! Thread safe, is in state stopped? - //! \threadsafe - bool isStopped() const - { - QReadLocker rl(&this->m_lock); - return this->m_stopped; - } - /*! * Set the update time * \param updatePeriodMs <=0 stops the timer @@ -116,9 +93,9 @@ namespace BlackMisc protected: //! Constructor - CThreadedReader() : m_lock(QReadWriteLock::Recursive) + CThreadedReader(QObject *owner) : CContinuousWorker(owner), + m_updateTimer(new QTimer(this)), m_lock(QReadWriteLock::Recursive) { - this->m_updateTimer = new QTimer(); } //! Has pending network replay @@ -137,20 +114,12 @@ namespace BlackMisc this->m_pendingFuture = future; } - //! Thread safe, mark as to be stopped - //! \threadsafe - void setStopFlag() - { - QWriteLocker wl(&this->m_lock); - this->m_stopped = true; - } - QTimer *m_updateTimer = nullptr; //!< update timer mutable QReadWriteLock m_lock; //!< lock private: QDateTime m_updateTimestamp; //!< when was file / resource read - bool m_stopped = false; //!< mark as stopped, threads should terminate + QFuture m_pendingFuture; //!< optional future to be stopped QNetworkReply *m_pendingNetworkReply = nullptr; //!< optional network reply to be stopped };