From 124f874b4aaa0fdb7d6eeda52847bf30e9169e93 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Mon, 17 Apr 2017 09:41:49 -0700 Subject: [PATCH] Make copy of the drivers list in SearchEngineImpl2 to avoid ConcurrentModificationError. I think this happens when a driver is disposed why search is in progress. So, we need to make defensive copies. This also makes me realize that we don't handle situations when a driver instance is disposed, but it has pending requests, such as getResult(), getIndex(), etc - actually any getXXX(), and search. As it is now, I think we just leave these Future(s) and they never complete. R=brianwilkerson@google.com BUG= Review-Url: https://codereview.chromium.org/2818163003 . --- .../services/search/search_engine_internal2.dart | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart index d9088a9d9d3..6f1336fd2b5 100644 --- a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart +++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart @@ -39,7 +39,8 @@ class SearchEngineImpl2 implements SearchEngine { @override Future> searchMemberDeclarations(String name) async { List allDeclarations = []; - for (AnalysisDriver driver in _drivers) { + List drivers = _drivers.toList(); + for (AnalysisDriver driver in drivers) { List elements = await driver.search.classMembers(name); allDeclarations.addAll(elements.map(_SearchMatch.forElement)); } @@ -49,7 +50,8 @@ class SearchEngineImpl2 implements SearchEngine { @override Future> searchMemberReferences(String name) async { List allResults = []; - for (AnalysisDriver driver in _drivers) { + List drivers = _drivers.toList(); + for (AnalysisDriver driver in drivers) { List results = await driver.search.unresolvedMemberReferences(name); allResults.addAll(results); @@ -60,7 +62,8 @@ class SearchEngineImpl2 implements SearchEngine { @override Future> searchReferences(Element element) async { List allResults = []; - for (AnalysisDriver driver in _drivers) { + List drivers = _drivers.toList(); + for (AnalysisDriver driver in drivers) { List results = await driver.search.references(element); allResults.addAll(results); } @@ -77,7 +80,8 @@ class SearchEngineImpl2 implements SearchEngine { Future> searchTopLevelDeclarations(String pattern) async { List allDeclarations = []; RegExp regExp = new RegExp(pattern); - for (AnalysisDriver driver in _drivers) { + List drivers = _drivers.toList(); + for (AnalysisDriver driver in drivers) { List elements = await driver.search.topLevelElements(regExp); allDeclarations.addAll(elements.map(_SearchMatch.forElement)); } @@ -86,7 +90,8 @@ class SearchEngineImpl2 implements SearchEngine { Future> _searchDirectSubtypes(ClassElement type) async { List allResults = []; - for (AnalysisDriver driver in _drivers) { + List drivers = _drivers.toList(); + for (AnalysisDriver driver in drivers) { List results = await driver.search.subTypes(type); allResults.addAll(results); }