From 27425b62e997cba6589d17f75896dfc7c5f3264d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 12 Jan 2016 14:05:05 +0100 Subject: [PATCH] Locator: Avoid use of QtConcurrent QtConcurrent limits resource usage to a global number of simultaneous threads. That means that if some QtConcurrent based algorithm currently grabs all threads, any other use of QtConcurrent blocks, which is not what we want. Use the new threading methods of C++11 instead, but still use QFuture(Interface) manually for status reporting. Task-number: QTCREATORBUG-14640 Change-Id: I8fecb43b5235da92c0d239e7dd5f2c108ab32ebf Reviewed-by: Orgad Shaneh Reviewed-by: Eike Ziller --- src/libs/utils/runextensions.h | 19 +++++++++++++++++++ .../coreplugin/locator/locatorfiltertest.cpp | 5 +++-- .../coreplugin/locator/locatorsearchutils.cpp | 2 +- .../coreplugin/locator/locatorsearchutils.h | 4 ++-- .../coreplugin/locator/locatorwidget.cpp | 3 ++- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/libs/utils/runextensions.h b/src/libs/utils/runextensions.h index 9f5d88a6a12..82854abd731 100644 --- a/src/libs/utils/runextensions.h +++ b/src/libs/utils/runextensions.h @@ -520,6 +520,16 @@ void blockingMapReduce(QFutureInterface futureInterface, const Con futureInterface.reportFinished(); } +template +void runAsyncImpl(QFutureInterface futureInterface, const Function &function, const Args&... args) +{ + futureInterface.reportStarted(); + function(futureInterface, args...); + if (futureInterface.isPaused()) + futureInterface.waitForResume(); + futureInterface.reportFinished(); +} + } // Internal template mapReduce(const Container &container, const InitFunction & return future; } +template +QFuture runAsync(Function &&function, Args&&... args) +{ + QFutureInterface futureInterface; + std::thread(Internal::runAsyncImpl, futureInterface, + std::forward(function), std::forward(args)...).detach(); + return futureInterface.future(); +} + } // Utils #endif // RUNEXTENSIONS_H diff --git a/src/plugins/coreplugin/locator/locatorfiltertest.cpp b/src/plugins/coreplugin/locator/locatorfiltertest.cpp index 18a960b4eea..641acc85a92 100644 --- a/src/plugins/coreplugin/locator/locatorfiltertest.cpp +++ b/src/plugins/coreplugin/locator/locatorfiltertest.cpp @@ -51,8 +51,9 @@ QList BasicLocatorFilterTest::matchesFor(const QString &sear doBeforeLocatorRun(); const QList filters = QList() << m_filter; m_filter->prepareSearch(searchText); - QFuture locatorSearch = QtConcurrent::run(Internal::runSearch, - filters, searchText); + QFuture locatorSearch = Utils::runAsync(&Internal::runSearch, + filters, + searchText); locatorSearch.waitForFinished(); doAfterLocatorRun(); return locatorSearch.results(); diff --git a/src/plugins/coreplugin/locator/locatorsearchutils.cpp b/src/plugins/coreplugin/locator/locatorsearchutils.cpp index b46e784996a..8cda9dee03c 100644 --- a/src/plugins/coreplugin/locator/locatorsearchutils.cpp +++ b/src/plugins/coreplugin/locator/locatorsearchutils.cpp @@ -47,7 +47,7 @@ uint qHash(const LocatorFilterEntry &entry) } // namespace Core void Core::Internal::runSearch(QFutureInterface &future, - QList filters, QString searchText) + const QList &filters, const QString &searchText) { QSet alreadyAdded; const bool checkDuplicates = (filters.size() > 1); diff --git a/src/plugins/coreplugin/locator/locatorsearchutils.h b/src/plugins/coreplugin/locator/locatorsearchutils.h index 88ab089318e..8d545d0dba3 100644 --- a/src/plugins/coreplugin/locator/locatorsearchutils.h +++ b/src/plugins/coreplugin/locator/locatorsearchutils.h @@ -37,8 +37,8 @@ namespace Core { namespace Internal { void CORE_EXPORT runSearch(QFutureInterface &future, - QList filters, - QString searchText); + const QList &filters, + const QString &searchText); } // namespace Internal } // namespace Core diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp index 02ac98f2ef6..7760b0e0838 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.cpp +++ b/src/plugins/coreplugin/locator/locatorwidget.cpp @@ -524,7 +524,8 @@ void LocatorWidget::updateCompletionList(const QString &text) foreach (ILocatorFilter *filter, filters) filter->prepareSearch(searchText); - QFuture future = QtConcurrent::run(runSearch, filters, searchText); + QFuture future = Utils::runAsync(&runSearch, filters, + QString(searchText)); m_entriesWatcher->setFuture(future); }