Optimize QEventDispatcherWinRT::runOnMainThread()

- use std::make_shared instead of QSharedPointer
  - two memory allocations saved
- co-locate semaphore and HRESULT object in a single State object
  - one more memory allocation saved
- pass the shared_ptr<State> by value into the runnable
  - two more memory allocations saved

Not only is the new code much faster, it's also much more readable.

Also use QSemaphoreReleaser, just in case the delegate should throw.

Change-Id: Ib99b9da86984d440d10b72e3071aa88099e24a1f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Marc Mutz 2019-09-04 19:30:08 +02:00
parent 6f4bc3942d
commit 236d4637b2

View File

@ -44,12 +44,13 @@
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QMutex> #include <QtCore/QMutex>
#include <QtCore/QSemaphore> #include <QtCore/QSemaphore>
#include <QtCore/QSharedPointer>
#include <QtCore/qfunctions_winrt.h> #include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h> #include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h> #include <private/qcoreapplication_p.h>
#include <functional> #include <functional>
#include <memory>
#include <wrl.h> #include <wrl.h>
#include <windows.foundation.h> #include <windows.foundation.h>
#include <windows.system.threading.h> #include <windows.system.threading.h>
@ -300,19 +301,19 @@ HRESULT QEventDispatcherWinRT::runOnMainThread(const std::function<HRESULT()> &d
if (QThread::currentThread() == QCoreApplication::instance()->thread()) if (QThread::currentThread() == QCoreApplication::instance()->thread())
return delegate(); return delegate();
auto semaphore = QSharedPointer<QSemaphore>(new QSemaphore); struct State {
auto ptrSemaphore = new QSharedPointer<QSemaphore>(semaphore); QSemaphore semaphore;
auto result = QSharedPointer<HRESULT>(new HRESULT); HRESULT result;
auto ptrResult = new QSharedPointer<HRESULT>(result); };
QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, ptrSemaphore, ptrResult]() { const auto state = std::make_shared<State>();
**ptrResult = delegate();
delete ptrResult; QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, state]() {
(*ptrSemaphore)->release(); const QSemaphoreReleaser releaser{state->semaphore};
delete ptrSemaphore; state->result = delegate();
}, nullptr); }, nullptr);
return semaphore->tryAcquire(1, timeout) ? *result : E_FAIL; return state->semaphore.tryAcquire(1, timeout) ? state->result : E_FAIL;
} }
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)