Files
pilotclient/src/blackcore/threadedreader.cpp
Klaus Basan 1ced7f3c0b refs #857, check if network is accessible in readers
* new read state "skipped"
* renamed to "isNetworkConnectedAndAccessible"
* checking before reading, which would only fail if network is not accessible
2017-02-24 00:08:55 +00:00

159 lines
4.8 KiB
C++

/* Copyright (C) 2013
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackcore/threadedreader.h"
#include "blackcore/application.h"
#include "blackmisc/network/networkutils.h"
#include "blackmisc/threadutils.h"
#include <QCoreApplication>
#include <QMetaObject>
#include <QReadLocker>
#include <QThread>
#include <QTimer>
#include <QWriteLocker>
using namespace BlackMisc;
using namespace BlackMisc::Network;
using namespace BlackCore::Vatsim;
namespace BlackCore
{
const CLogCategoryList &CThreadedReader::getLogCategories()
{
static const BlackMisc::CLogCategoryList cats { BlackMisc::CLogCategory::worker() };
return cats;
}
CThreadedReader::CThreadedReader(QObject *owner, const QString &name) :
CContinuousWorker(owner, name),
m_updateTimer(new QTimer(this))
{
connect(m_updateTimer, &QTimer::timeout, this, &CThreadedReader::doWork);
m_updateTimer->setSingleShot(true);
}
CThreadedReader::~CThreadedReader()
{
gracefulShutdown();
}
qint64 CThreadedReader::lastModifiedMsSinceEpoch(QNetworkReply *nwReply) const
{
return CNetworkUtils::lastModifiedMsSinceEpoch(nwReply);
}
QDateTime CThreadedReader::getUpdateTimestamp() const
{
QReadLocker lock(&this->m_lock);
return this->m_updateTimestamp;
}
void CThreadedReader::setUpdateTimestamp(const QDateTime &updateTimestamp)
{
QWriteLocker lock(&this->m_lock);
this->m_updateTimestamp = updateTimestamp;
}
bool CThreadedReader::updatedWithinLastMs(qint64 timeLastMs)
{
QDateTime dt(getUpdateTimestamp());
if (dt.isNull() || !dt.isValid()) { return false; }
qint64 delta = QDateTime::currentMSecsSinceEpoch() - dt.toMSecsSinceEpoch();
return delta <= timeLastMs;
}
bool CThreadedReader::isNetworkConnectedAndAccessible() const
{
return sApp->isNetworkConnectedAndAccessible();
}
void CThreadedReader::gracefulShutdown()
{
// if not in main thread stop, otherwise it makes no sense to abandon
this->m_shutdown = true;
if (!CThreadUtils::isCurrentThreadObjectThread(this))
{
this->abandonAndWait();
}
}
void CThreadedReader::startReader()
{
Q_ASSERT(m_initialTime > 0);
QTimer::singleShot(m_initialTime, this, [ = ] { this->doWork(); });
}
void CThreadedReader::pauseReader()
{
QTimer::singleShot(0, m_updateTimer, &QTimer::stop);
}
bool CThreadedReader::isShuttingDown() const
{
if (!sApp) { return true; } // sApp object is gone, whole system shutdown
if (this->m_shutdown) { return true; } // marked as shutdown
if (this->isAbandoned()) { return true; } // worker abandoned
return false;
}
bool CThreadedReader::didContentChange(const QString &content, int startPosition)
{
uint oldHash = 0;
{
QReadLocker rl(&this->m_lock);
oldHash = this->m_contentHash;
}
uint newHash = qHash(startPosition < 0 ? content : content.mid(startPosition));
if (oldHash == newHash) { return false; }
{
QWriteLocker wl(&this->m_lock);
this->m_contentHash = newHash;
}
return true;
}
bool CThreadedReader::isMarkedAsFailed() const
{
return this->m_markedAsFailed;
}
void CThreadedReader::setMarkedAsFailed(bool failed)
{
this->m_markedAsFailed = failed;
}
void CThreadedReader::threadAssertCheck() const
{
Q_ASSERT_X(QCoreApplication::instance()->thread() != QThread::currentThread(), Q_FUNC_INFO, "Needs to run in own thread");
Q_ASSERT_X(QObject::thread() == QThread::currentThread(), Q_FUNC_INFO, "Wrong object thread");
}
void CThreadedReader::setInitialAndPeriodicTime(int initialTime, int periodicTime)
{
m_initialTime = initialTime;
m_periodicTime = periodicTime;
if (m_updateTimer->isActive())
{
int oldPeriodicTime = m_updateTimer->interval();
int delta = m_periodicTime - oldPeriodicTime + m_updateTimer->remainingTime();
m_updateTimer->start(qMax(delta, 0));
}
}
void CThreadedReader::doWork()
{
if (isFinished()) { return; }
doWorkImpl();
Q_ASSERT(m_periodicTime > 0);
m_updateTimer->start(m_periodicTime);
}
} // namespace