Ref T314 Rework CContinuousWorker::finish to invoke deleteLater in proper sequence.

This commit is contained in:
Mat Sutcliffe
2018-09-29 20:40:45 +01:00
committed by Klaus Basan
parent c98454ff8a
commit bad31ab428

View File

@@ -89,12 +89,14 @@ namespace BlackMisc
QThread *workerThread = this->thread(); QThread *workerThread = this->thread();
Q_ASSERT_X(workerThread->thread()->isRunning(), Q_FUNC_INFO, "Owner thread's event loop already ended"); Q_ASSERT_X(workerThread->thread()->isRunning(), Q_FUNC_INFO, "Owner thread's event loop already ended");
this->moveToThread(workerThread->thread()); // move worker back to the thread which constructed it, so there is no race on deletion // MS 2018-09 Now we post the DeferredDelete event from within the worker thread, but rely on it being dispatched
Q_ASSERT_X(this->thread() == workerThread->thread(), Q_FUNC_INFO, "moveToThread failed"); // by the owner thread. Posted events are moved along with the object when moveToThread is called.
// We also connect its destroyed signal to delete the worker thread at the same time.
this->deleteLater();
connect(this, &QObject::destroyed, workerThread, &QObject::deleteLater);
//! \todo KB 2018-97 new syntax not yet supported on Jenkins QMetaObject::invokeMethod(workerThread, &CWorker::deleteLater) this->moveToThread(workerThread->thread()); // move worker back to the thread which constructed it, so there is no race on deletion
QMetaObject::invokeMethod(workerThread, "deleteLater"); // must not access the worker beyond this point, as it now lives in the owner's thread and could be deleted at any moment
QMetaObject::invokeMethod(this, "deleteLater");
} }
const CLogCategoryList &CWorkerBase::getLogCategories() const CLogCategoryList &CWorkerBase::getLogCategories()
@@ -166,8 +168,8 @@ namespace BlackMisc
{ {
this->setEnabled(false); this->setEnabled(false);
// already in different thread? otherwise return // already in owner's thread? then return
if (CThreadUtils::isApplicationThreadObjectThread(this)) { return; } if (this->thread() == m_owner->thread()) { return; }
// remark: cannot stop timer here, as I am normally not in the correct thread // remark: cannot stop timer here, as I am normally not in the correct thread
thread()->quit(); thread()->quit();
@@ -177,8 +179,8 @@ namespace BlackMisc
{ {
this->setEnabled(false); this->setEnabled(false);
// already in application (main) thread? => return // already in owner's thread? then return
if (CThreadUtils::isApplicationThreadObjectThread(this)) { return; } if (this->thread() == m_owner->thread()) { return; }
// called by own thread, will deadlock, return // called by own thread, will deadlock, return
if (CThreadUtils::isCurrentThreadObjectThread(this)) { return; } if (CThreadUtils::isCurrentThreadObjectThread(this)) { return; }
@@ -229,12 +231,13 @@ namespace BlackMisc
Q_ASSERT_X(m_owner->thread()->isRunning(), Q_FUNC_INFO, "Owner thread's event loop already ended"); Q_ASSERT_X(m_owner->thread()->isRunning(), Q_FUNC_INFO, "Owner thread's event loop already ended");
QThread *workerThread = this->thread(); // MS 2018-09 Now we post the DeferredDelete event from within the worker thread, but rely on it being dispatched
this->moveToThread(m_owner->thread()); // move worker back to the thread which constructed it, so there is no race on deletion // by the owner thread. Posted events are moved along with the object when moveToThread is called.
Q_ASSERT_X(this->thread() == m_owner->thread(), Q_FUNC_INFO, "moveToThread failed"); // We also connect its destroyed signal to delete the worker thread at the same time.
this->deleteLater();
connect(this, &QObject::destroyed, this->thread(), &QObject::deleteLater);
//! \todo new syntax not yet supported on Jenkins QMetaObject::invokeMethod(workerThread, &CWorker::deleteLater) this->moveToThread(m_owner->thread()); // move worker back to the thread which constructed it, so there is no race on deletion
QMetaObject::invokeMethod(workerThread, "deleteLater"); // must not access the worker beyond this point, as it now lives in the owner's thread and could be deleted at any moment
QMetaObject::invokeMethod(this, "deleteLater");
} }
} // ns } // ns