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 05c267673f and 6fc39f0c41
00c5673ae80d03d115bf3739

Change-Id: I93c607c879e8ba6ef60f94719812edb3df43a154
Task-number: QTCREATORBUG-12875
Task-number: QTCREATORBUG-12592
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
This commit is contained in:
Eike Ziller
2014-09-22 10:37:08 +02:00
parent a6014c1039
commit 10cb7abe17
2 changed files with 14 additions and 6 deletions

View File

@@ -478,12 +478,18 @@ QList<ILocatorFilter *> LocatorWidget::filtersFor(const QString &text, QString &
void LocatorWidget::updateCompletionList(const QString &text) void LocatorWidget::updateCompletionList(const QString &text)
{ {
m_updateRequested = true; 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; QString searchText;
const QList<ILocatorFilter *> filters = filtersFor(text, searchText); const QList<ILocatorFilter *> filters = filtersFor(text, searchText);
// cancel the old future
m_entriesWatcher->future().cancel();
QFuture<LocatorFilterEntry> future = QtConcurrent::run(runSearch, filters, searchText); QFuture<LocatorFilterEntry> future = QtConcurrent::run(runSearch, filters, searchText);
m_entriesWatcher->setFuture(future); m_entriesWatcher->setFuture(future);
} }
@@ -492,8 +498,9 @@ void LocatorWidget::updateEntries()
{ {
m_updateRequested = false; m_updateRequested = false;
if (m_entriesWatcher->future().isCanceled()) { if (m_entriesWatcher->future().isCanceled()) {
// reset to usable state const QString text = m_requestedCompletionText;
m_acceptRequested = false; m_requestedCompletionText.clear();
updateCompletionList(text);
return; return;
} }

View File

@@ -94,6 +94,7 @@ private:
QTimer *m_showPopupTimer; QTimer *m_showPopupTimer;
QFutureWatcher<LocatorFilterEntry> *m_entriesWatcher; QFutureWatcher<LocatorFilterEntry> *m_entriesWatcher;
QMap<Core::Id, QAction *> m_filterActionMap; QMap<Core::Id, QAction *> m_filterActionMap;
QString m_requestedCompletionText;
bool m_updateRequested; bool m_updateRequested;
bool m_acceptRequested; bool m_acceptRequested;
bool m_possibleToolTipRequest; bool m_possibleToolTipRequest;