From 9235f3232e6b7c5ffad7a49eb7ee1068bcce8fd7 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 20 Apr 2020 20:45:36 +0200 Subject: [PATCH] Improvements during shutdown * stop listeners * check if airspace monitor and FSD still exist * stop listeners on "aboutToShutdown()" * check for processEventsFor(500) --- src/blackcore/context/contextnetworkimpl.cpp | 122 +++++++++++++----- src/blackcore/context/contextnetworkimpl.h | 6 + .../context/contextsimulatorimpl.cpp | 8 +- src/blackcore/simulator.cpp | 18 ++- src/blackcore/simulator.h | 6 +- .../fsxcommon/simulatorfsxcommon.cpp | 17 ++- 6 files changed, 139 insertions(+), 38 deletions(-) diff --git a/src/blackcore/context/contextnetworkimpl.cpp b/src/blackcore/context/contextnetworkimpl.cpp index f16fcca19..35763d390 100644 --- a/src/blackcore/context/contextnetworkimpl.cpp +++ b/src/blackcore/context/contextnetworkimpl.cpp @@ -126,8 +126,8 @@ namespace BlackCore void CContextNetwork::setSimulationEnvironmentProvider(ISimulationEnvironmentProvider *provider) { - if (m_airspace) { m_airspace->setSimulationEnvironmentProvider(provider); } - if (m_fsdClient) { m_fsdClient->setSimulationEnvironmentProvider(provider); } + if (this->canUseAirspaceMonitor()) { m_airspace->setSimulationEnvironmentProvider(provider); } + if (this->canUseFsd()) { m_fsdClient->setSimulationEnvironmentProvider(provider); } } CContextNetwork::~CContextNetwork() @@ -137,25 +137,25 @@ namespace BlackCore CAircraftSituationList CContextNetwork::remoteAircraftSituations(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->remoteAircraftSituations(callsign); } CAircraftSituation CContextNetwork::remoteAircraftSituation(const Aviation::CCallsign &callsign, int index) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->remoteAircraftSituation(callsign, index); } MillisecondsMinMaxMean CContextNetwork::remoteAircraftSituationsTimestampDifferenceMinMaxMean(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->remoteAircraftSituationsTimestampDifferenceMinMaxMean(callsign); } CAircraftSituationList CContextNetwork::latestRemoteAircraftSituations() const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->latestRemoteAircraftSituations(); } @@ -167,43 +167,43 @@ namespace BlackCore CAircraftPartsList CContextNetwork::remoteAircraftParts(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->remoteAircraftParts(callsign); } int CContextNetwork::remoteAircraftPartsCount(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return 0; } return m_airspace->remoteAircraftPartsCount(callsign); } int CContextNetwork::remoteAircraftSituationsCount(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return 0; } return m_airspace->remoteAircraftSituationsCount(callsign); } bool CContextNetwork::isRemoteAircraftSupportingParts(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return false; } return m_airspace->isRemoteAircraftSupportingParts(callsign); } CCallsignSet CContextNetwork::remoteAircraftSupportingParts() const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->remoteAircraftSupportingParts(); } - Aviation::CAircraftSituationChangeList CContextNetwork::remoteAircraftSituationChanges(const CCallsign &callsign) const + CAircraftSituationChangeList CContextNetwork::remoteAircraftSituationChanges(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->remoteAircraftSituationChanges(callsign); } int CContextNetwork::remoteAircraftSituationChangesCount(const CCallsign &callsign) const { - Q_ASSERT(m_airspace); + if (!this->canUseAirspaceMonitor()) { return {}; } return m_airspace->remoteAircraftSituationChangesCount(callsign); } @@ -222,17 +222,27 @@ namespace BlackCore { this->disconnect(); // all signals if (this->isConnected()) { this->disconnectFromNetwork(); } - if (m_airspace) { m_airspace->gracefulShutdown(); } if (m_fsdClient) { m_fsdClient->gracefulShutdown(); m_fsdClient->setClientProvider(nullptr); + m_fsdClient->deleteLater(); + m_fsdClient = nullptr; + } + + if (m_airspace) + { + m_airspace->gracefulShutdown(); + m_airspace->deleteLater(); + m_airspace = nullptr; } } CStatusMessage CContextNetwork::connectToNetwork(const CServer &server, const QString &extraLiveryString, bool sendLivery, const QString &extraModelString, bool sendModelString, const CCallsign &partnerCallsign, CLoginMode mode) { + if (!this->canUseFsd()) { return { CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityInfo, u"Invalid FSD state (shutdown)") }; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } + QString msg; if (!server.getUser().hasCredentials()) { return CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityError, u"Invalid user credentials"); } if (!this->ownAircraft().getAircraftIcaoCode().hasDesignator()) { return CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityError, u"Invalid ICAO data for own aircraft"); } @@ -295,17 +305,20 @@ namespace BlackCore CServer CContextNetwork::getConnectedServer() const { + if (!this->canUseFsd()) { return {}; } return this->isConnected() ? m_fsdClient->getServer() : CServer(); } CLoginMode CContextNetwork::getLoginMode() const { + if (!this->canUseFsd()) { return {}; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_fsdClient->getLoginMode(); } CStatusMessage CContextNetwork::disconnectFromNetwork() { + if (!this->canUseFsd()) { return { CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityInfo, u"Invalid FSD state (shutdown)") }; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (m_fsdClient->isConnected() || m_fsdClient->isPendingConnection()) { @@ -320,19 +333,25 @@ namespace BlackCore bool CContextNetwork::isConnected() const { + if (!this->canUseFsd()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_fsdClient->isConnected(); } bool CContextNetwork::isPendingConnection() const { + if (!this->canUseFsd()) { return false; } return m_fsdClient->isPendingConnection(); } bool CContextNetwork::parseCommandLine(const QString &commandLine, const CIdentifier &originator) { Q_UNUSED(originator;) - if (commandLine.isEmpty()) { return false; } + + if (!this->canUseAirspaceMonitor()) { return false; } + if (!this->canUseFsd()) { return false; } + if (commandLine.isEmpty()) { return false; } + static const QStringList cmds({ ".msg", ".m", ".chat", ".altos", ".altoffset", ".addtimeos", ".addtimeoffset", ".wallop", ".watchdog", ".reinit", ".reinitialize", ".enable", ".disable", ".ignore", ".unignore", ".fsd" }); CSimpleCommandParser parser(cmds); parser.parse(commandLine); @@ -548,21 +567,22 @@ namespace BlackCore CFlightPlan CContextNetwork::loadFlightPlanFromNetwork(const CCallsign &callsign) const { + if (!this->canUseFsd()) { return {}; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_airspace->loadFlightPlanFromNetwork(callsign); } CUserList CContextNetwork::getUsers() const { + if (!this->canUseAirspaceMonitor()) { return {}; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_airspace->getUsers(); } CUserList CContextNetwork::getUsersForCallsigns(const CCallsignSet &callsigns) const { + if (!this->canUseAirspaceMonitor() || callsigns.isEmpty()) { return {}; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - CUserList users; - if (callsigns.isEmpty()) return users; return m_airspace->getUsersForCallsigns(callsigns); } @@ -578,39 +598,46 @@ namespace BlackCore CClientList CContextNetwork::getClients() const { + if (!this->canUseAirspaceMonitor()) { return {}; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_airspace->getClients(); } CClientList CContextNetwork::getClientsForCallsigns(const CCallsignSet &callsigns) const { + if (!this->canUseAirspaceMonitor()) { return {}; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_airspace->getClientsForCallsigns(callsigns); } bool CContextNetwork::setOtherClient(const CClient &client) { + if (!this->canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_airspace->setOtherClient(client); } int CContextNetwork::removeClient(const Aviation::CCallsign &callsign) { + if (!this->canUseAirspaceMonitor()) { return 0; } return m_airspace->removeClient(callsign); } bool CContextNetwork::autoAdjustCientGndCapability(const Aviation::CAircraftSituation &situation) { + if (!this->canUseAirspaceMonitor()) { return false; } return m_airspace->autoAdjustCientGndCapability(situation); } bool CContextNetwork::addClientGndCapability(const CCallsign &callsign) { + if (!this->canUseAirspaceMonitor()) { return false; } return m_airspace->addClientGndCapability(callsign); } bool CContextNetwork::setClientGndCapability(const Aviation::CCallsign &callsign, bool supportGndFlag) { + if (!this->canUseAirspaceMonitor()) { return false; } return m_airspace->setClientGndCapability(callsign, supportGndFlag); } @@ -716,6 +743,16 @@ namespace BlackCore } } + bool CContextNetwork::canUseFsd() const + { + return sApp && !sApp->isShuttingDown() && m_fsdClient; + } + + bool CContextNetwork::canUseAirspaceMonitor() const + { + return sApp && !sApp->isShuttingDown() && m_airspace; + } + void CContextNetwork::updateMetars(const CMetarList &metars) { if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } @@ -1027,7 +1064,7 @@ namespace BlackCore void CContextNetwork::requestAircraftDataUpdates() { - Q_ASSERT(m_airspace); + if (!canUseAirspaceMonitor()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (!this->isConnected()) { return; } @@ -1037,7 +1074,7 @@ namespace BlackCore void CContextNetwork::requestAtisUpdates() { - Q_ASSERT(m_airspace); + if (!canUseAirspaceMonitor()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (!this->isConnected()) { return; } @@ -1047,7 +1084,7 @@ namespace BlackCore bool CContextNetwork::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRendering) { - Q_ASSERT(m_airspace); + if (!canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << enabledForRendering; } const bool c = m_airspace->updateAircraftEnabled(callsign, enabledForRendering); if (c) @@ -1061,13 +1098,14 @@ namespace BlackCore bool CContextNetwork::setAircraftEnabledFlag(const CCallsign &callsign, bool enabledForRendering) { + if (!canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; } return m_airspace->setAircraftEnabledFlag(callsign, enabledForRendering); } bool CContextNetwork::updateAircraftModel(const CCallsign &callsign, const CAircraftModel &model, const CIdentifier &originator) { - Q_ASSERT(m_airspace); + if (!canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << model; } const bool c = m_airspace->updateAircraftModel(callsign, model, originator); if (c) @@ -1081,6 +1119,7 @@ namespace BlackCore bool CContextNetwork::updateAircraftNetworkModel(const CCallsign &callsign, const CAircraftModel &model, const CIdentifier &originator) { + if (!canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << model; } const bool c = m_airspace->updateAircraftNetworkModel(callsign, model, originator); if (c) @@ -1093,6 +1132,7 @@ namespace BlackCore bool CContextNetwork::updateFastPositionEnabled(const CCallsign &callsign, bool enableFastPositonUpdates) { + if (!canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << enableFastPositonUpdates; } const bool c = m_airspace->updateFastPositionEnabled(callsign, enableFastPositonUpdates); if (c) @@ -1119,6 +1159,7 @@ namespace BlackCore bool CContextNetwork::updateCG(const Aviation::CCallsign &callsign, const CLength &cg) { + if (!canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << cg.valueRoundedWithUnit(1); } const bool c = m_airspace->updateCG(callsign, cg); return c; @@ -1126,6 +1167,7 @@ namespace BlackCore CCallsignSet CContextNetwork::updateCGForModel(const QString &modelString, const CLength &cg) { + if (!canUseAirspaceMonitor()) { return {}; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << modelString << cg.valueRoundedWithUnit(1); } const CCallsignSet set = m_airspace->updateCGForModel(modelString, cg); return set; @@ -1133,6 +1175,7 @@ namespace BlackCore bool CContextNetwork::updateCGAndModelString(const CCallsign &callsign, const CLength &cg, const QString &modelString) { + if (!canUseAirspaceMonitor()) { return false; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << cg.valueRoundedWithUnit(1) << modelString; } const bool c = m_airspace->updateCGAndModelString(callsign, cg, modelString); return c; @@ -1140,71 +1183,84 @@ namespace BlackCore void CContextNetwork::requestAtcBookingsUpdate() const { + if (!canUseAirspaceMonitor()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } m_airspace->requestAtcBookingsUpdate(); } bool CContextNetwork::updateAircraftRendered(const CCallsign &callsign, bool rendered) { + if (!canUseAirspaceMonitor()) { return false; } const bool c = m_airspace->updateAircraftRendered(callsign, rendered); return c; } int CContextNetwork::updateMultipleAircraftRendered(const CCallsignSet &callsigns, bool rendered) { + if (!canUseAirspaceMonitor()) { return 0; } const int c = m_airspace->updateMultipleAircraftRendered(callsigns, rendered); return c; } int CContextNetwork::updateMultipleAircraftEnabled(const CCallsignSet &callsigns, bool enabled) { + if (!canUseAirspaceMonitor()) { return 0; } const int c = m_airspace->updateMultipleAircraftEnabled(callsigns, enabled); return c; } int CContextNetwork::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition) { + if (!canUseAirspaceMonitor()) { return 0; } return m_airspace->updateAircraftGroundElevation(callsign, elevation, info, setForOnGroundPosition); } void CContextNetwork::updateMarkAllAsNotRendered() { + if (!canUseAirspaceMonitor()) { return; } m_airspace->updateMarkAllAsNotRendered(); } CLength CContextNetwork::getCGFromDB(const CCallsign &callsign) const { + if (!canUseAirspaceMonitor()) { return {}; } return m_airspace->getCGFromDB(callsign); } CLength CContextNetwork::getCGFromDB(const QString &modelString) const { + if (!canUseAirspaceMonitor()) { return {}; } return m_airspace->getCGFromDB(modelString); } void CContextNetwork::rememberCGFromDB(const CLength &cgFromDB, const CCallsign &callsign) { + if (!canUseAirspaceMonitor()) { return; } m_airspace->rememberCGFromDB(cgFromDB, callsign); } void CContextNetwork::rememberCGFromDB(const CLength &cgFromDB, const QString &modelString) { + if (!canUseAirspaceMonitor()) { return; } m_airspace->rememberCGFromDB(cgFromDB, modelString); } int CContextNetwork::reInitializeAllAircraft() { + if (!canUseAirspaceMonitor()) { return 0; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } return m_airspace->reInitializeAllAircraft(); } CAirspaceAircraftSnapshot CContextNetwork::getLatestAirspaceAircraftSnapshot() const { + if (!canUseAirspaceMonitor()) { return {}; } return m_airspace->getLatestAirspaceAircraftSnapshot(); } CElevationPlane CContextNetwork::averageElevationOfNonMovingAircraft(const CAircraftSituation &reference, const CLength &range, int minValues, int sufficientValues) const { + if (!canUseAirspaceMonitor()) { return {}; } return m_airspace->averageElevationOfNonMovingAircraft(reference, range, minValues, sufficientValues); } @@ -1220,21 +1276,25 @@ namespace BlackCore CClient CContextNetwork::getClientOrDefaultForCallsign(const Aviation::CCallsign &callsign) const { + if (!canUseAirspaceMonitor()) { return {}; } return m_airspace->getClientOrDefaultForCallsign(callsign); } bool CContextNetwork::hasClientInfo(const Aviation::CCallsign &callsign) const { + if (!canUseAirspaceMonitor()) { return false; } return m_airspace->hasClientInfo(callsign); } bool CContextNetwork::addNewClient(const CClient &client) { + if (!canUseAirspaceMonitor()) { return false; } return m_airspace->addNewClient(client); } int CContextNetwork::updateOrAddClient(const Aviation::CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues) { + if (!canUseAirspaceMonitor()) { return 0; } return m_airspace->updateOrAddClient(callsign, vm, skipEqualValues); } @@ -1254,46 +1314,44 @@ namespace BlackCore QString CContextNetwork::getLibraryInfo(bool detailed) const { + if (!this->canUseFsd()) { return QString(); } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << detailed; } - Q_ASSERT(m_fsdClient); return ""; } void CContextNetwork::testRequestAircraftConfig(const CCallsign &callsign) { + if (!this->canUseFsd()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; } - Q_ASSERT(m_fsdClient); m_fsdClient->sendClientQueryAircraftConfig(callsign); } void CContextNetwork::testCreateDummyOnlineAtcStations(int number) { + if (!this->canUseAirspaceMonitor()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << number; } m_airspace->testCreateDummyOnlineAtcStations(number); } void CContextNetwork::testAddAircraftParts(const CCallsign &callsign, const CAircraftParts &parts, bool incremental) { + if (!this->canUseAirspaceMonitor()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts << incremental; } m_airspace->testAddAircraftParts(callsign, parts, incremental); } void CContextNetwork::testReceivedAtisMessage(const CCallsign &callsign, const CInformationMessage &msg) { + if (!this->canUseFsd()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign.asString(); } - if (this->fsdClient()) - { - emit this->fsdClient()->atisReplyReceived(callsign, msg); - } + emit this->fsdClient()->atisReplyReceived(callsign, msg); } void CContextNetwork::testReceivedTextMessages(const CTextMessageList &textMessages) { + if (!this->canUseFsd()) { return; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << textMessages.toQString(); } - if (this->fsdClient()) - { - emit this->fsdClient()->textMessagesReceived(textMessages); - } + emit this->fsdClient()->textMessagesReceived(textMessages); } CMetar CContextNetwork::getMetarForAirport(const CAirportIcaoCode &airportIcaoCode) const diff --git a/src/blackcore/context/contextnetworkimpl.h b/src/blackcore/context/contextnetworkimpl.h index 60a511a1c..65be3af76 100644 --- a/src/blackcore/context/contextnetworkimpl.h +++ b/src/blackcore/context/contextnetworkimpl.h @@ -352,6 +352,12 @@ namespace BlackCore //! Status of simulator changed //! \ingroup crosscontextfunction void xCtxSimulatorStatusChanged(int status); + + //! Can FSD be used? + bool canUseFsd() const; + + //! Can the airspace monitor be used be used? + bool canUseAirspaceMonitor() const; }; } // ns } // ns diff --git a/src/blackcore/context/contextsimulatorimpl.cpp b/src/blackcore/context/contextsimulatorimpl.cpp index ccbe8a9bd..6ae13432a 100644 --- a/src/blackcore/context/contextsimulatorimpl.cpp +++ b/src/blackcore/context/contextsimulatorimpl.cpp @@ -144,8 +144,14 @@ namespace BlackCore m_validator->deleteLater(); m_validator = nullptr; } + this->stopSimulatorListeners(); this->disconnect(); this->unloadSimulatorPlugin(); + + // give listeners a head start + // if simconnect is running remotely it can take a while until it shutdowns + m_listenersThread.quit(); + m_listenersThread.wait(10 * 1000); } CSimulatorPluginInfoList CContextSimulator::getAvailableSimulatorPlugins() const @@ -934,7 +940,7 @@ namespace BlackCore { if (!m_simulatorPlugin.first.isUnspecified()) { return; } - stopSimulatorListeners(); + this->stopSimulatorListeners(); const QStringList enabledSimulators = m_enabledSimulators.getThreadLocal(); const CSimulatorPluginInfoList allSimulators = m_plugins->getAvailableSimulatorPlugins(); for (const CSimulatorPluginInfo &s : allSimulators) diff --git a/src/blackcore/simulator.cpp b/src/blackcore/simulator.cpp index c2270bc27..585966465 100644 --- a/src/blackcore/simulator.cpp +++ b/src/blackcore/simulator.cpp @@ -1430,8 +1430,15 @@ namespace BlackCore this->setObjectName("ISimulatorListener:" + info.toQString()); // stop listener after it reports simulator ready - const bool s = connect(this, &ISimulatorListener::simulatorStarted, this, &ISimulatorListener::stop, Qt::QueuedConnection); + bool s = connect(this, &ISimulatorListener::simulatorStarted, this, &ISimulatorListener::stop, Qt::QueuedConnection); Q_ASSERT_X(s, Q_FUNC_INFO, "connect failed"); + + if (sApp) + { + s = connect(sApp, &CApplication::aboutToShutdown, this, &ISimulatorListener::onAboutToShutdown, Qt::QueuedConnection); + Q_ASSERT_X(s, Q_FUNC_INFO, "connect failed"); + } + Q_UNUSED(s) } @@ -1442,7 +1449,14 @@ namespace BlackCore bool ISimulatorListener::isShuttingDown() const { - return (!sApp || sApp->isShuttingDown()); + return (!sApp || sApp->isShuttingDown() || m_aboutToShutdown); + } + + void ISimulatorListener::onAboutToShutdown() + { + if (!m_aboutToShutdown) { return; } + m_aboutToShutdown = true; + this->stop(); } void ISimulatorListener::start() diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 52172216a..8f8566fd0 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -720,8 +720,12 @@ namespace BlackCore virtual void checkImpl() = 0; private: + //! swift will shutdown + void onAboutToShutdown(); + BlackMisc::Simulation::CSimulatorPluginInfo m_info; - std::atomic_bool m_isRunning { false }; + std::atomic_bool m_isRunning { false }; + std::atomic_bool m_aboutToShutdown { false }; // swift will shutdown }; //! Factory pattern class to create instances of ISimulator diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index cdf5c07c4..289120d15 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -33,6 +33,7 @@ #include #include #include +#include using namespace BlackConfig; using namespace BlackMisc; @@ -2823,13 +2824,15 @@ namespace BlackSimPlugin if (!m_timer.isActive()) { return; } if (this->isShuttingDown()) { return; } - m_timer.start(); // restart because we will check just now QPointer myself(this); QTimer::singleShot(0, this, [ = ] { if (!myself || !sApp || sApp->isShuttingDown()) { return; } this->checkConnection(); }); + + // restart because we have just checked now + m_timer.start(); } QString CSimulatorFsxCommonListener::backendInfo() const @@ -2841,6 +2844,7 @@ namespace BlackSimPlugin void CSimulatorFsxCommonListener::checkConnection() { if (this->isShuttingDown()) { return; } + QElapsedTimer t; t.start(); Q_ASSERT_X(!CThreadUtils::isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background"); HANDLE hSimConnect; HRESULT result = SimConnect_Open(&hSimConnect, sApp->swiftVersionChar(), nullptr, 0, nullptr, 0); @@ -2851,11 +2855,18 @@ namespace BlackSimPlugin // blocks remote calls -> RESTART for (int i = 0; !check && i < 3 && !this->isShuttingDown(); i++) { + if (this->thread()->isInterruptionRequested()) + { + m_timer.stop(); + check = false; + break; + } + // result not always in first dispatch as we first have to obtain simulator name result = SimConnect_CallDispatch(hSimConnect, CSimulatorFsxCommonListener::SimConnectProc, this); if (isFailure(result)) { break; } // means serious failure check = this->checkVersionAndSimulator(); - if (!check && sApp) { sApp->processEventsFor(500); } + if (!check && sApp) { CApplication::processEventsFor(500); } } } SimConnect_Close(hSimConnect); @@ -2864,6 +2875,8 @@ namespace BlackSimPlugin { emit this->simulatorStarted(this->getPluginInfo()); } + + CLogMessage(this).debug(u"Checked sim connection in %1ms") << t.elapsed(); } bool CSimulatorFsxCommonListener::checkVersionAndSimulator() const