Simplify CThreadedReader to avoid race conditions

refs #731
This commit is contained in:
Roland Winklmeier
2016-08-11 23:18:51 +02:00
committed by Mathew Sutcliffe
parent 6b0412d68d
commit 4733c72553
9 changed files with 86 additions and 130 deletions

View File

@@ -45,7 +45,7 @@ namespace BlackCore
CVatsimBookingReader::CVatsimBookingReader(QObject *owner) :
CThreadedReader(owner, "CVatsimBookingReader")
{
this->connect(this->m_updateTimer, &QTimer::timeout, this, &CVatsimBookingReader::ps_read);
reloadSettings();
}
void CVatsimBookingReader::readInBackgroundThread()
@@ -60,22 +60,20 @@ namespace BlackCore
// void
}
CReaderSettings CVatsimBookingReader::getSettings() const
void CVatsimBookingReader::doWorkImpl()
{
return this->m_settings.get();
ps_read();
}
void CVatsimBookingReader::ps_read()
{
if (!this->isNetworkAvailable())
{
CLogMessage(this).warning("No network, cancel bookings reader");
this->m_updateTimer->stop();
CLogMessage(this).warning("No network, cannot read VATSIM bookings");
return;
}
this->threadAssertCheck();
this->restartTimer(true); // when timer active, restart so we cause no undesired reads
Q_ASSERT_X(sApp, Q_FUNC_INFO, "No application");
const QUrl url(sApp->getGlobalSetup().getVatsimBookingsUrl());
@@ -122,7 +120,6 @@ namespace BlackCore
if (this->getUpdateTimestamp() == updateTimestamp) return; // nothing to do
// save parsing and all follow up actions if nothing changed
this->restartTimer(); // do not consider time for reading
bool changed = this->didContentChange(xmlData, xmlData.indexOf("</timestamp>"));
if (!changed)
{
@@ -203,5 +200,12 @@ namespace BlackCore
emit this->dataRead(CEntityFlags::BookingEntity, CEntityFlags::ReadFailed, 0);
}
} // method
void CVatsimBookingReader::reloadSettings()
{
CReaderSettings s = m_settings.get();
setInitialAndPeriodicTime(s.getInitialTime().toMs(), s.getPeriodicTime().toMs());
}
} // ns
} // ns

View File

@@ -48,7 +48,7 @@ namespace BlackCore
//! \name BlackCore::CThreadedReader overrides
//! @{
virtual void cleanup() override;
virtual BlackCore::Vatsim::CReaderSettings getSettings() const override;
virtual void doWorkImpl() override;
//! @}
private slots:
@@ -60,7 +60,9 @@ namespace BlackCore
void ps_read();
private:
BlackMisc::CSettingReadOnly<BlackCore::Vatsim::TVatsimBookings> m_settings { this };
void reloadSettings();
BlackMisc::CSettingReadOnly<BlackCore::Vatsim::TVatsimBookings> m_settings { this, &CVatsimBookingReader::reloadSettings };
};
} // ns
} // ns

View File

@@ -60,7 +60,7 @@ namespace BlackCore
CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner) :
CThreadedReader(owner, "CVatsimDataFileReader")
{
this->connect(this->m_updateTimer, &QTimer::timeout, this, &CVatsimDataFileReader::ps_read);
reloadSettings();
}
CSimulatedAircraftList CVatsimDataFileReader::getAircraft() const
@@ -178,22 +178,19 @@ namespace BlackCore
// void
}
CReaderSettings CVatsimDataFileReader::getSettings() const
void CVatsimDataFileReader::doWorkImpl()
{
return this->m_settings.get();
ps_read();
}
void CVatsimDataFileReader::ps_read()
{
if (!this->isNetworkAvailable())
{
CLogMessage(this).warning("No network, cancel data file reader");
this->m_updateTimer->stop();
CLogMessage(this).warning("No network, cannot read VATSIM data file");
return;
}
this->threadAssertCheck();
this->restartTimer(true); // when timer active, restart so we cause no undesired reads
// round robin for load balancing
// remark: Don't use QThread to run network operations in the background
@@ -228,7 +225,6 @@ namespace BlackCore
nwReply->close(); // close asap
if (dataFileData.isEmpty()) { return; }
this->restartTimer(); // do not consider time for reading
if (!this->didContentChange(dataFileData)) // Quick check by hash
{
CLogMessage(this).info("VATSIM file has same content, skipped");
@@ -440,6 +436,12 @@ namespace BlackCore
}
}
void CVatsimDataFileReader::reloadSettings()
{
CReaderSettings s = m_settings.get();
setInitialAndPeriodicTime(s.getInitialTime().toMs(), s.getPeriodicTime().toMs());
}
const QMap<QString, QString> CVatsimDataFileReader::clientPartsToMap(const QString &currentLine, const QStringList &clientSectionAttributes)
{
QMap<QString, QString> parts;

View File

@@ -128,7 +128,7 @@ namespace BlackCore
//! \name BlackCore::CThreadedReader overrides
//! @{
virtual void cleanup() override;
virtual BlackCore::Vatsim::CReaderSettings getSettings() const override;
virtual void doWorkImpl() override;
//! @}
private slots:
@@ -139,10 +139,12 @@ namespace BlackCore
void ps_read();
private:
void reloadSettings();
BlackMisc::Aviation::CAtcStationList m_atcStations;
BlackMisc::Simulation::CSimulatedAircraftList m_aircraft;
BlackMisc::CData<BlackCore::Data::TVatsimSetup> m_lastGoodSetup { this };
BlackMisc::CSettingReadOnly<BlackCore::Vatsim::TVatsimDataFile> m_settings { this };
BlackMisc::CSettingReadOnly<BlackCore::Vatsim::TVatsimDataFile> m_settings { this, &CVatsimDataFileReader::reloadSettings };
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Network::CVoiceCapabilities> m_voiceCapabilities;
//! Split line and assign values to their corresponding attribute names

View File

@@ -41,7 +41,7 @@ namespace BlackCore
CVatsimMetarReader::CVatsimMetarReader(QObject *owner) :
CThreadedReader(owner, "CVatsimMetarReader")
{
this->connect(this->m_updateTimer, &QTimer::timeout, this, &CVatsimMetarReader::readMetars);
reloadSettings();
}
void CVatsimMetarReader::readInBackgroundThread()
@@ -72,9 +72,9 @@ namespace BlackCore
// void
}
CReaderSettings CVatsimMetarReader::getSettings() const
void CVatsimMetarReader::doWorkImpl()
{
return m_settings.get();
readMetars();
}
void CVatsimMetarReader::readMetars()
@@ -82,12 +82,10 @@ namespace BlackCore
if (this->isAbandoned()) { return; }
if (!this->isNetworkAvailable())
{
CLogMessage(this).warning("No network, cancel METAR reader");
this->m_updateTimer->stop();
CLogMessage(this).warning("No network, cannot read METARs");
return;
}
this->threadAssertCheck();
this->restartTimer(true); // when timer active, restart so we cause no undesired reads
CFailoverUrlList urls(sApp->getVatsimMetarUrls());
const CUrl url(urls.obtainNextWorkingUrl(true));
@@ -117,7 +115,6 @@ namespace BlackCore
QString metarData = nwReply->readAll();
nwReply->close(); // close asap
this->restartTimer(); // do not consider time for reading
if (!this->didContentChange(metarData)) // Quick check by hash
{
CLogMessage(this).info("METAR file has same content, skipped");
@@ -154,5 +151,12 @@ namespace BlackCore
emit dataRead(CEntityFlags::MetarEntity, CEntityFlags::ReadFailed, 0);
}
} // method
void CVatsimMetarReader::reloadSettings()
{
CReaderSettings s = m_settings.get();
setInitialAndPeriodicTime(s.getInitialTime().toMs(), s.getPeriodicTime().toMs());
}
} // ns
} // ns

View File

@@ -63,7 +63,7 @@ namespace BlackCore
//! \name BlackCore::CThreadedReader overrides
//! @{
virtual void cleanup() override;
virtual BlackCore::Vatsim::CReaderSettings getSettings() const override;
virtual void doWorkImpl() override;
//! @}
private:
@@ -74,10 +74,12 @@ namespace BlackCore
//! Do reading
void readMetars();
void reloadSettings();
private:
BlackMisc::Weather::CMetarDecoder m_metarDecoder;
BlackMisc::Weather::CMetarList m_metars;
BlackMisc::CSettingReadOnly<BlackCore::Vatsim::TVatsimMetars> m_settings { this };
BlackMisc::CSettingReadOnly<BlackCore::Vatsim::TVatsimMetars> m_settings { this, &CVatsimMetarReader::reloadSettings };
};
} // ns
} // ns