forked from qt-creator/qt-creator
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 with05c267673f
and6fc39f0c41
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:
@@ -478,12 +478,18 @@ QList<ILocatorFilter *> 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<ILocatorFilter *> filters = filtersFor(text, searchText);
|
||||
|
||||
// cancel the old future
|
||||
m_entriesWatcher->future().cancel();
|
||||
|
||||
QFuture<LocatorFilterEntry> 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;
|
||||
}
|
||||
|
||||
|
@@ -94,6 +94,7 @@ private:
|
||||
QTimer *m_showPopupTimer;
|
||||
QFutureWatcher<LocatorFilterEntry> *m_entriesWatcher;
|
||||
QMap<Core::Id, QAction *> m_filterActionMap;
|
||||
QString m_requestedCompletionText;
|
||||
bool m_updateRequested;
|
||||
bool m_acceptRequested;
|
||||
bool m_possibleToolTipRequest;
|
||||
|
Reference in New Issue
Block a user