From 3c4743c66cca4137510e090659b0400700754ec4 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 May 2023 14:51:15 +0200 Subject: [PATCH] Future-proof QGenericRunnableHelper Collapse the two function pointers into a single one, taking an Op enum. Add a possible return value (void*) and extra argument (also void*). The intent is to allow extensions in a BC way, e.g. cloning. We can't add new function pointers (sizeof changes), so we need to fold everything into a single function. Change-Id: Id0f3f74149c61e4e65622aeabfd2fcea3c6d7fb3 Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot --- src/corelib/thread/qrunnable.h | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/corelib/thread/qrunnable.h b/src/corelib/thread/qrunnable.h index 37a99ea8413..67ce203458c 100644 --- a/src/corelib/thread/qrunnable.h +++ b/src/corelib/thread/qrunnable.h @@ -38,27 +38,38 @@ protected: // Type erasure, to only instantiate a non-virtual class per Callable: class QGenericRunnableHelperBase { - using OpFn = void(*)(QGenericRunnableHelperBase *); - OpFn runFn; - OpFn destroyFn; protected: - constexpr explicit QGenericRunnableHelperBase(OpFn fn, OpFn del) noexcept : runFn(fn), destroyFn(del) {} + enum class Op { + Run, + Destroy, + }; + using OpFn = void* (*)(Op, QGenericRunnableHelperBase *, void*); + OpFn fn; + protected: + constexpr explicit QGenericRunnableHelperBase(OpFn f) noexcept : fn(f) {} ~QGenericRunnableHelperBase() = default; public: - void run() { runFn(this); } - void destroy() { destroyFn(this); } + void run() { fn(Op::Run, this, nullptr); } + void destroy() { fn(Op::Destroy, this, nullptr); } }; template class QGenericRunnableHelper : public QGenericRunnableHelperBase { Callable m_functionToRun; + static void *impl(Op op, QGenericRunnableHelperBase *that, [[maybe_unused]] void *arg) + { + const auto _this = static_cast(that); + switch (op) { + case Op::Run: _this->m_functionToRun(); break; + case Op::Destroy: delete _this; break; + } + return nullptr; + } public: template - QGenericRunnableHelper(UniCallable &&functionToRun) noexcept : - QGenericRunnableHelperBase( - [](QGenericRunnableHelperBase *that) { static_cast(that)->m_functionToRun(); }, - [](QGenericRunnableHelperBase *that) { delete static_cast(that); }), + explicit QGenericRunnableHelper(UniCallable &&functionToRun) noexcept + : QGenericRunnableHelperBase(&impl), m_functionToRun(std::forward(functionToRun)) { }