From 10cb7abe1762188c901685264b60515c3b15023b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 22 Sep 2014 10:37:08 +0200 Subject: Locator: Fix the fix of the deadlock The all/current project searches use metacalls on the UI thread to work around thread-unsafety of the Project::allFiles method, so we cannot jus t block the UI thread to wait for the old search to cancel. On the other hand, many of the ILocatorFilter::matchesFor implementation s do not work when they are run in multiple threads simultaneously (most implementations access unguarded member variables, help index filter tend s to crash), so we _do_ have to wait for the search to cancel before sta rting a new thread. Broke with 05c267673f43ecbb0ae4c44adc7d02a690435f8b and 6fc39f0c41c248be 00c5673ae80d03d115bf3739 Change-Id: I93c607c879e8ba6ef60f94719812edb3df43a154 Task-number: QTCREATORBUG-12875 Task-number: QTCREATORBUG-12592 Reviewed-by: Christian Kandeler --- src/plugins/coreplugin/locator/locatorwidget.cpp | 19 +++++++++++++------ src/plugins/coreplugin/locator/locatorwidget.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp index 07e80e557f..8d3ef982f9 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.cpp +++ b/src/plugins/coreplugin/locator/locatorwidget.cpp @@ -478,12 +478,18 @@ QList LocatorWidget::filtersFor(const QString &text, QString & void LocatorWidget::updateCompletionList(const QString &text) { m_updateRequested = true; + if (m_entriesWatcher->future().isRunning()) { + // Cancel the old future. We may not just block the UI thread to wait for the search to + // actually cancel, so try again when the finshed signal of the watcher ends up in + // updateEntries() (which will call updateCompletionList again with the + // requestedCompletionText) + m_requestedCompletionText = text; + m_entriesWatcher->future().cancel(); + return; + } + QString searchText; const QList filters = filtersFor(text, searchText); - - // cancel the old future - m_entriesWatcher->future().cancel(); - QFuture future = QtConcurrent::run(runSearch, filters, searchText); m_entriesWatcher->setFuture(future); } @@ -492,8 +498,9 @@ void LocatorWidget::updateEntries() { m_updateRequested = false; if (m_entriesWatcher->future().isCanceled()) { - // reset to usable state - m_acceptRequested = false; + const QString text = m_requestedCompletionText; + m_requestedCompletionText.clear(); + updateCompletionList(text); return; } diff --git a/src/plugins/coreplugin/locator/locatorwidget.h b/src/plugins/coreplugin/locator/locatorwidget.h index a7e6021f6b..dca841b82b 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.h +++ b/src/plugins/coreplugin/locator/locatorwidget.h @@ -94,6 +94,7 @@ private: QTimer *m_showPopupTimer; QFutureWatcher *m_entriesWatcher; QMap m_filterActionMap; + QString m_requestedCompletionText; bool m_updateRequested; bool m_acceptRequested; bool m_possibleToolTipRequest; -- cgit v1.2.1