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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user