diff --git a/QGCCommon.pri b/QGCCommon.pri index 2fb1d80163d7cd4f493a828fe8f92b261c4b657f..de0c5166560f16139533100ce7b9dd69a36301af 100644 --- a/QGCCommon.pri +++ b/QGCCommon.pri @@ -221,7 +221,7 @@ WindowsBuild { # ReleaseBuild { - DEFINES += QT_NO_DEBUG + DEFINES += QT_NO_DEBUG QT_MESSAGELOGCONTEXT CONFIG += force_debug_info # Enable debugging symbols on release builds !iOSBuild { CONFIG += ltcg # Turn on link time code generation diff --git a/src/ui/MAVLinkDecoder.cc b/src/ui/MAVLinkDecoder.cc index 5b02b32b33b319e6347a33c0411ec611684c1b44..ff22edf6be8e308d1dd5cd5ee19eb2ad8d6db833 100644 --- a/src/ui/MAVLinkDecoder.cc +++ b/src/ui/MAVLinkDecoder.cc @@ -3,10 +3,9 @@ #include -MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol, QObject *parent) : - QThread() +MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol) : + QThread(), creationThread(QThread::currentThread()) { - Q_UNUSED(parent); // We're doing it wrong - because the Qt folks got the API wrong: // http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ moveToThread(this); @@ -52,6 +51,7 @@ MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol, QObject *parent) : // textMessageFilter.insert(MAVLINK_MSG_ID_HIGHRES_IMU, false); connect(protocol, &MAVLinkProtocol::messageReceived, this, &MAVLinkDecoder::receiveMessage); + connect(this, &MAVLinkDecoder::finish, this, &QThread::quit); start(LowPriority); } @@ -63,6 +63,7 @@ MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol, QObject *parent) : void MAVLinkDecoder::run() { exec(); + moveToThread(creationThread); } void MAVLinkDecoder::receiveMessage(LinkInterface* link,mavlink_message_t message) diff --git a/src/ui/MAVLinkDecoder.h b/src/ui/MAVLinkDecoder.h index eaa1909061e87b7fe57482b2ff22000c9ba4031a..ffe761f37e2bc48f061540a874d1209e2face131 100644 --- a/src/ui/MAVLinkDecoder.h +++ b/src/ui/MAVLinkDecoder.h @@ -8,13 +8,14 @@ class MAVLinkDecoder : public QThread { Q_OBJECT public: - MAVLinkDecoder(MAVLinkProtocol* protocol, QObject *parent = 0); + MAVLinkDecoder(MAVLinkProtocol* protocol); void run(); signals: void textMessageReceived(int uasid, int componentid, int severity, const QString& text); void valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant& value, const quint64 msec); + void finish(); ///< Trigger a thread safe shutdown public slots: /** @brief Receive one message from the protocol and decode it */ @@ -35,6 +36,7 @@ protected: quint64 onboardTimeOffset[cMessageIds]; ///< Offset of onboard time from Unix epoch (of the receiving GCS) qint64 onboardToGCSUnixTimeOffsetAndDelay[cMessageIds]; ///< Offset of onboard time and GCS Unix time quint64 firstOnboardTime[cMessageIds]; ///< First seen onboard time + QThread* creationThread; ///< QThread on which the object is created }; #endif // MAVLINKDECODER_H diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 6d925bc4635b3b55f147ffa3cffab8c14884fcc2..5b1fb93b48adfc58b6eca2b18411a22cc2577c95 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -274,6 +274,11 @@ MainWindow::MainWindow() MainWindow::~MainWindow() { + // Enforce thread-safe shutdown of the mavlink decoder + mavlinkDecoder->finish(); + mavlinkDecoder->wait(1000); + mavlinkDecoder->deleteLater(); + // This needs to happen before we get into the QWidget dtor // otherwise the QML engine reads freed data and tries to // destroy MainWindow a second time. @@ -290,8 +295,7 @@ QString MainWindow::_getWindowGeometryKey() void MainWindow::_buildCommonWidgets(void) { // Add generic MAVLink decoder - // TODO: This is never deleted - mavlinkDecoder = new MAVLinkDecoder(qgcApp()->toolbox()->mavlinkProtocol(), this); + mavlinkDecoder = new MAVLinkDecoder(qgcApp()->toolbox()->mavlinkProtocol()); connect(mavlinkDecoder.data(), &MAVLinkDecoder::valueChanged, this, &MainWindow::valueChanged); // Log player