From 846ed7c50d7b9891c1095e7b90b6f4ba4b3e414a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 11 Feb 2019 18:11:04 +0100 Subject: [PATCH] ClangRefactoring: Add thread safety for progress report Task-number: QTCREATORBUG-21950 Change-Id: Id067e23a501253f3b73671f6939164e314b5c8a9 Reviewed-by: Ivan Donchevskii --- .../clangpchmanagerbackendmain.cpp | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index 80bb8886aa8..58d749ec3a7 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -72,6 +72,48 @@ using ClangBackEnd::FilePathCache; using ClangBackEnd::FilePathView; using ClangBackEnd::TimeStamp; +#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) +template +class CallableEvent : public QEvent +{ +public: + using Callable = std::decay_t; + CallableEvent(Callable &&callable) + : QEvent(QEvent::None) + , callable(std::move(callable)) + {} + CallableEvent(const Callable &callable) + : QEvent(QEvent::None) + , callable(callable) + {} + + ~CallableEvent() { callable(); } + +public: + Callable callable; +}; + +template +void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) +{ + if (QThread *thread = qobject_cast(object)) + object = QAbstractEventDispatcher::instance(thread); + + QCoreApplication::postEvent(object, + new CallableEvent(std::forward(callable)), + Qt::HighEventPriority); +} +#else +template +void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) +{ + if (QThread *thread = qobject_cast(object)) + object = QAbstractEventDispatcher::instance(thread); + + QMetaObject::invokeMethod(object, std::forward(callable)); +} +#endif + class PchManagerApplication final : public QCoreApplication { public: @@ -182,8 +224,9 @@ struct Data // because we have a cycle dependency clangPchManagerServer, includeWatcher}; PrecompiledHeaderStorage<> preCompiledHeaderStorage{database}; - ClangBackEnd::ProgressCounter progressCounter{ - [&](int progress, int total) { clangPchManagerServer.setProgress(progress, total); }}; + ClangBackEnd::ProgressCounter progressCounter{[&](int progress, int total) { + executeInLoop([&] { clangPchManagerServer.setProgress(progress, total); }); + }}; ClangBackEnd::PchTaskQueue pchTaskQueue{systemTaskScheduler, projectTaskScheduler, progressCounter,