diff --git a/src/blackmisc/loghandler.cpp b/src/blackmisc/loghandler.cpp index cc10322e7..7b8e8eb2a 100644 --- a/src/blackmisc/loghandler.cpp +++ b/src/blackmisc/loghandler.cpp @@ -213,7 +213,7 @@ namespace BlackMisc if (CLogHandler::instance()->thread() != QThread::currentThread()) { Q_ASSERT(thread() == QThread::currentThread()); - singleShot(0, CLogHandler::instance()->thread(), this, [ = ]() { changeSubscription(pattern); }); + singleShot(0, CLogHandler::instance(), [pattern, self = QPointer(this)]() { if (self) { self->changeSubscription(pattern); } }); return; } @@ -232,7 +232,7 @@ namespace BlackMisc if (CLogHandler::instance()->thread() != QThread::currentThread()) { Q_ASSERT(thread() == QThread::currentThread()); - singleShot(0, CLogHandler::instance()->thread(), this, [ = ]() { unsubscribe(); }); + singleShot(0, CLogHandler::instance(), [self = QPointer(this)]() { if (self) { self->unsubscribe(); } }); return; } @@ -248,7 +248,7 @@ namespace BlackMisc if (CLogHandler::instance()->thread() != QThread::currentThread()) { Q_ASSERT(thread() == QThread::currentThread()); - singleShot(0, CLogHandler::instance()->thread(), this, [ = ]() { inheritConsoleOutput(); }); + singleShot(0, CLogHandler::instance(), [self = QPointer(this)]() { if (self) { self->inheritConsoleOutput(); } }); return; } @@ -264,7 +264,7 @@ namespace BlackMisc if (CLogHandler::instance()->thread() != QThread::currentThread()) { Q_ASSERT(thread() == QThread::currentThread()); - singleShot(0, CLogHandler::instance()->thread(), this, [ = ]() { enableConsoleOutput(enable); }); + singleShot(0, CLogHandler::instance(), [enable, self = QPointer(this)]() { if (self) { self->enableConsoleOutput(enable); } }); return; } diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index dae73e789..84057843f 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -37,30 +37,14 @@ namespace BlackMisc { - //! \private Class for synchronizing singleShot() task with its owner. - class BLACKMISC_EXPORT CSingleShotController : public QObject - { - Q_OBJECT - public: - CSingleShotController(QObject *parent) : QObject(parent), m_strongRef(QSharedPointer::create(0)) {} - ~CSingleShotController() { auto wr = weakRef(); m_strongRef.clear(); waitForNull(wr); } - QWeakPointer weakRef() const { return m_strongRef.toWeakRef(); } - private: - static void waitForNull(QWeakPointer wp) { while (wp) { QThread::msleep(10); } } - QSharedPointer m_strongRef; // pointee type doesn't matter, we only care about the reference count - }; - /*! - * Starts a single-shot timer which will run in an existing thread and call a task when it times out. + * Starts a single-shot timer which will call a task in the thread of the given object when it times out. * - * Useful when a worker thread wants to push small sub-tasks back to the thread which spawned it. - * - * If an owner pointer is specified, then the task may be cancelled if the owner is deleted, but the - * owner will not be deleted while the task is running (its destructor will wait for the task to end). + * Differs from QTimer::singleShot in that this implementation interacts better with QObject::moveToThread. */ //! @{ template - void singleShot(int msec, QThread *target, F &&task) + void singleShot(int msec, QObject *target, F &&task) { QSharedPointer timer(new QTimer, [](QObject *o) { QMetaObject::invokeMethod(o, "deleteLater"); }); timer->setSingleShot(true); @@ -73,17 +57,6 @@ namespace BlackMisc }); QMetaObject::invokeMethod(timer.data(), "start", Q_ARG(int, msec)); } - template - void singleShot(int msec, QThread *target, QObject *owner, F task) - { - Q_ASSERT(QThread::currentThread() == owner->thread()); - auto weakRef = (new CSingleShotController(owner))->weakRef(); - singleShot(msec, target, [ = ]() - { - auto strongRef = weakRef.toStrongRef(); - if (strongRef) { task(); } - }); - } //! @} /*!