diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 59c93aa6e6..f3ddc84758 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -312,6 +312,7 @@ void QEventLoop::quit() class QEventLoopLockerPrivate { + friend class QEventLoopLocker; public: explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop) : QEventLoopLockerPrivate(loop, EventLoop) @@ -331,22 +332,6 @@ public: app->ref(); } - ~QEventLoopLockerPrivate() - { - switch (type()) - { - case EventLoop: - loop()->deref(); - break; - case Thread: - thread()->deref(); - break; - default: - app()->deref(); - break; - } - } - private: QEventLoopPrivate *loop() const { return static_cast(pointer()); } QThreadPrivate *thread() const { return static_cast(pointer()); } @@ -432,9 +417,26 @@ QEventLoopLocker::QEventLoopLocker(QThread *thread) */ QEventLoopLocker::~QEventLoopLocker() { + visit([](auto p) { p->deref(); }); delete d_ptr; } +/*! + \internal +*/ +template +void QEventLoopLocker::visit(Func f) const +{ + using Type = QEventLoopLockerPrivate::Type; + const auto ptr = d_ptr->pointer(); + switch (d_ptr->type()) { + case Type::EventLoop: return f(static_cast(ptr)); + case Type::Thread: return f(static_cast(ptr)); + case Type::Application: return f(static_cast(ptr)); + } + Q_UNREACHABLE(); +} + QT_END_NAMESPACE #include "moc_qeventloop.cpp" diff --git a/src/corelib/kernel/qeventloop.h b/src/corelib/kernel/qeventloop.h index 3c444e8fd3..265ec76047 100644 --- a/src/corelib/kernel/qeventloop.h +++ b/src/corelib/kernel/qeventloop.h @@ -63,7 +63,14 @@ public: private: Q_DISABLE_COPY(QEventLoopLocker) + + // + // Private implementation details. + // Do not call from public inline API! + // QEventLoopLockerPrivate *d_ptr; + template + void visit(Func func) const; }; QT_END_NAMESPACE