refs #502, move the thread checks into own class in blackmisc

* we want to clean up the freefunctions anyway
* allows to use check in blackmisc namespace
This commit is contained in:
Klaus Basan
2015-11-04 02:38:18 +01:00
committed by Mathew Sutcliffe
parent e11e8e5716
commit 98b86b6f27
9 changed files with 109 additions and 57 deletions

View File

@@ -10,6 +10,7 @@
#include "blackcore/airspace_analyzer.h"
#include "blackcore/blackcorefreefunctions.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/threadutilities.h"
#include <QDateTime>
using namespace BlackMisc;
@@ -173,8 +174,8 @@ namespace BlackCore
void CAirspaceAnalyzer::analyzeAirspace()
{
Q_ASSERT_X(!isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background thread");
Q_ASSERT_X(!isApplicationThreadObjectThread(this), Q_FUNC_INFO, "Expect to run in background thread affinity");
Q_ASSERT_X(!CThreadUtils::isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background thread");
Q_ASSERT_X(!CThreadUtils::isApplicationThreadObjectThread(this), Q_FUNC_INFO, "Expect to run in background thread affinity");
bool restricted, enabled;
int maxAircraft;

View File

@@ -17,6 +17,7 @@
#include "blackmisc/logmessage.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/propertyindexallclasses.h"
#include "blackmisc/threadutilities.h"
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
@@ -569,7 +570,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_receivedBookings(const CAtcStationList &bookedStations)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
if (bookedStations.isEmpty())
{
this->m_atcStationsBooked.clear();
@@ -589,7 +590,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_receivedDataFile()
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
for (auto client = this->m_otherClients.begin(); client != this->m_otherClients.end(); ++client)
{
if (client->hasSpecifiedVoiceCapabilities()) { continue; } // we already have voice caps
@@ -632,7 +633,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_atcPositionUpdate(const CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency, const CCoordinateGeodetic &position, const BlackMisc::PhysicalQuantities::CLength &range)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
if (!this->m_connected) { return; }
CAtcStationList stationsWithCallsign = this->m_atcStationsOnline.findByCallsign(callsign);
if (stationsWithCallsign.isEmpty())
@@ -682,7 +683,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_atcControllerDisconnected(const CCallsign &callsign)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
this->m_otherClients.removeByCallsign(callsign);
if (this->m_atcStationsOnline.containsCallsign(callsign))
@@ -699,7 +700,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_atisReceived(const CCallsign &callsign, const CInformationMessage &atisMessage)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
if (!this->m_connected || callsign.isEmpty()) return;
CPropertyIndexVariantMap vm(CAtcStation::IndexAtis, CVariant::from(atisMessage));
int changedOnline = this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm);
@@ -713,7 +714,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_atisVoiceRoomReceived(const CCallsign &callsign, const QString &url)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
if (!this->m_connected) { return; }
QString trimmedUrl = url.trimmed();
CPropertyIndexVariantMap vm({ CAtcStation::IndexVoiceRoom, CVoiceRoom::IndexUrl }, trimmedUrl);
@@ -740,7 +741,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_atisLogoffTimeReceived(const CCallsign &callsign, const QString &zuluTime)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
if (!this->m_connected) { return; }
if (zuluTime.length() == 4)
{
@@ -764,7 +765,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_icaoCodesReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator, const QString &livery)
{
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "not in main thread");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "not in main thread");
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "no callsign");
if (!this->m_connected) { return; }
@@ -844,7 +845,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_aircraftUpdateReceived(const CAircraftSituation &situation, const CTransponder &transponder)
{
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Called in different thread");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Called in different thread");
if (!this->m_connected) { return; }
CCallsign callsign(situation.getCallsign());
@@ -934,7 +935,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_aircraftInterimUpdateReceived(const CAircraftSituation &situation)
{
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Called in different thread");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Called in different thread");
if (!this->m_connected) { return; }
CCallsign callsign(situation.getCallsign());
@@ -975,7 +976,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_pilotDisconnected(const CCallsign &callsign)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
// in case of inconsistencies I always remove here
this->m_otherClients.removeByCallsign(callsign);
@@ -1001,7 +1002,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_frequencyReceived(const CCallsign &callsign, const CFrequency &frequency)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
// update
int changed;
@@ -1015,7 +1016,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull)
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
CSimulatedAircraft simAircraft(getAircraftInRangeForCallsign(callsign));
@@ -1050,7 +1051,7 @@ namespace BlackCore
void CAirspaceMonitor::ps_sendInterimPositions()
{
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this));
if (!this->m_connected || !m_sendInterimPositions) { return; }
CSimulatedAircraftList aircrafts = m_aircraftInRange.findBy(&CSimulatedAircraft::fastPositionUpdates, true);
m_network->sendInterimPositions(aircrafts.getCallsigns());

View File

@@ -27,26 +27,4 @@ namespace BlackCore
BlackCore::Data::CGlobalSetup::registerMetadata();
}
bool isCurrentThreadObjectThread(QObject *toBeTested)
{
Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject");
if (!toBeTested) { return false; }
if (!toBeTested->thread()) { return false; }
return (QThread::currentThread() == toBeTested->thread());
}
bool isApplicationThreadObjectThread(QObject *toBeTested)
{
Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject");
if (!toBeTested) { return false; }
if (!toBeTested->thread()) { return false; }
return (QCoreApplication::instance()->thread() == toBeTested->thread());
}
bool isCurrentThreadApplicationThread()
{
return (QCoreApplication::instance()->thread() == QThread::currentThread());
}
} // namespace

View File

@@ -14,18 +14,6 @@ namespace BlackCore
//! Register all relevant metadata in BlackCore
BLACKCORE_EXPORT void registerMetadata();
//! Is the current thread the QObject's thread?
//! \remarks can be used as ASSERT check for threaded objects
BLACKCORE_EXPORT bool isCurrentThreadObjectThread(QObject *toBeTested);
//! Is the application thread the QObject's thread?
//! \remarks can be used as ASSERT check for threaded objects
BLACKCORE_EXPORT bool isApplicationThreadObjectThread(QObject *toBeTested);
//! Is the current thread the Application thread?
//! \remarks can be used as ASSERT check for threaded objects
BLACKCORE_EXPORT bool isCurrentThreadApplicationThread();
} // BlackCore
} // ns
#endif // guard

View File

@@ -18,6 +18,7 @@
#include "blackmisc/propertyindexvariantmap.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/loghandler.h"
#include "blackmisc/threadutilities.h"
#include <QPluginLoader>
#include <QLibrary>
@@ -278,7 +279,7 @@ namespace BlackCore
Q_ASSERT(getIContextApplication());
Q_ASSERT(getIContextApplication()->isUsingImplementingObject());
Q_ASSERT(!simulatorInfo.isUnspecified());
Q_ASSERT(BlackCore::isCurrentThreadApplicationThread()); // only run in main thread
Q_ASSERT(CThreadUtils::isCurrentThreadApplicationThread()); // only run in main thread
// Is the plugin already loaded?
if (!m_simulatorPlugin.first.isUnspecified() &&

View File

@@ -13,6 +13,7 @@
#include "blackmisc/logmessage.h"
#include "blackmisc/loghandler.h"
#include "blackmisc/collection.h"
#include "blackmisc/threadutilities.h"
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
@@ -305,7 +306,7 @@ namespace BlackCore
// when changing back from restricted->unrestricted an one time update is required
if (!snapshot.isRestricted() && !snapshot.isRestrictionChanged()) { return; }
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Needs to run in object thread");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Needs to run in object thread");
Q_ASSERT_X(snapshot.generatingThreadName() != QThread::currentThread()->objectName(), Q_FUNC_INFO, "Expect snapshot from background thread");
// restricted snapshot values?

View File

@@ -0,0 +1,37 @@
/* Copyright (C) 2015
* 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 "threadutilities.h"
#include <QThread>
#include <QCoreApplication>
namespace BlackMisc
{
bool CThreadUtils::isCurrentThreadObjectThread(QObject *toBeTested)
{
Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject");
if (!toBeTested) { return false; }
if (!toBeTested->thread()) { return false; }
return (QThread::currentThread() == toBeTested->thread());
}
bool CThreadUtils::isApplicationThreadObjectThread(QObject *toBeTested)
{
Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject");
if (!toBeTested) { return false; }
if (!toBeTested->thread()) { return false; }
return (QCoreApplication::instance()->thread() == toBeTested->thread());
}
bool CThreadUtils::isCurrentThreadApplicationThread()
{
return (QCoreApplication::instance()->thread() == QThread::currentThread());
}
} // ns

View File

@@ -0,0 +1,44 @@
/* Copyright (C) 2015
* 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.
*/
//! \file
#ifndef BLACKMISC_CTHREADUTILITIES_H
#define BLACKMISC_CTHREADUTILITIES_H
#include "blackmiscexport.h"
#include <QObject>
#include <QDebug>
namespace BlackMisc
{
/*!
* Utility class for threaded operations
*/
class BLACKMISC_EXPORT CThreadUtils
{
public:
//! No constructor
CThreadUtils() = delete;
//! Is the current thread the QObject's thread?
//! \remarks can be used as ASSERT check for threaded objects
static bool isCurrentThreadObjectThread(QObject *toBeTested);
//! Is the application thread the QObject's thread?
//! \remarks can be used as ASSERT check for threaded objects
static bool isApplicationThreadObjectThread(QObject *toBeTested);
//! Is the current thread the Application thread?
//! \remarks can be used as ASSERT check for threaded objects
static bool isCurrentThreadApplicationThread();
};
} // ns
#endif // guard

View File

@@ -18,6 +18,7 @@
#include "blackmisc/project.h"
#include "blackmisc/aviation/airportlist.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/threadutilities.h"
#include "blackmisc/simulation/fscommon/fscommonutil.h"
#include <QTimer>
@@ -128,7 +129,7 @@ namespace BlackSimPlugin
bool CSimulatorFsx::physicallyAddRemoteAircraft(const Simulation::CSimulatedAircraft &newRemoteAircraft)
{
CCallsign callsign(newRemoteAircraft.getCallsign());
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign");
if (callsign.isEmpty()) { return false; }
@@ -505,7 +506,7 @@ namespace BlackSimPlugin
bool CSimulatorFsx::physicallyRemoveRemoteAircraft(const CCallsign &callsign)
{
// only remove from sim
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "wrong thred");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "wrong thred");
if (!m_simConnectObjects.contains(callsign)) { return false; }
return physicallyRemoveRemoteAircraft(m_simConnectObjects.value(callsign));
}
@@ -614,7 +615,7 @@ namespace BlackSimPlugin
{
static_assert(sizeof(DataDefinitionRemoteAircraftParts) == 120, "DataDefinitionRemoteAircraftParts has an incorrect size.");
Q_ASSERT_X(this->m_interpolator, Q_FUNC_INFO, "missing interpolator");
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
// nothing to do, reset request id and exit
if (this->isPaused() && this->m_pausedSimFreezesInterpolation) { return; } // no interpolation while paused
@@ -845,7 +846,7 @@ namespace BlackSimPlugin
void CSimulatorFsxListener::ps_checkConnection()
{
Q_ASSERT_X(!BlackCore::isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background");
Q_ASSERT_X(!CThreadUtils::isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background");
HANDLE hSimConnect;
HRESULT result = SimConnect_Open(&hSimConnect, BlackMisc::CProject::swiftVersionChar(), nullptr, 0, 0, 0);
SimConnect_Close(hSimConnect);