1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 522411 - ConcurrentModificationException below

CModelListener.addLastRecentlyUsed (thrown in
LinkedHashMap$LinkedHashIterator.nextNode)

CModelListener reacts on all the resource events, but is NOT MT-safe due
the not guarded access to the "fLRUs" map, which can be iterated AND
modified at same time by different threads.

This commit introduces synchronization on the "fLRUs" map field. This is
safe as the field is private and not exposed to other objects, and the
code inside synchronized block does not call into other locks which
might interfere.

Change-Id: I3e601f02e93e40a1454c9a581fa46378904eb3dc
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
This commit is contained in:
Andrey Loskutov 2017-09-18 17:01:06 +02:00
parent 4e7354e1b0
commit 398307d9bb

View file

@ -39,7 +39,7 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL
public static boolean sSuppressUpdateOfLastRecentlyUsed = false;
private PDOMManager fManager;
private LinkedHashMap<ITranslationUnit, ITranslationUnit> fLRUs= new LinkedHashMap<ITranslationUnit, ITranslationUnit>(UPDATE_LR_CHANGED_FILES_COUNT, 0.75f, true) {
private final LinkedHashMap<ITranslationUnit, ITranslationUnit> fLRUs= new LinkedHashMap<ITranslationUnit, ITranslationUnit>(UPDATE_LR_CHANGED_FILES_COUNT, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<ITranslationUnit, ITranslationUnit> eldest) {
return size() > UPDATE_LR_CHANGED_FILES_COUNT;
@ -131,23 +131,25 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL
}
if (count > 0) {
if (addLRUs) {
for (final ITranslationUnit tu : fLRUs.keySet()) {
if (tu.getResource().exists()) {
final ICProject cproject= tu.getCProject();
DeltaAnalyzer analyzer= changeMap.get(cproject);
if (analyzer == null) {
analyzer= new DeltaAnalyzer();
changeMap.put(cproject, analyzer);
synchronized(fLRUs) {
if (addLRUs) {
for (final ITranslationUnit tu : fLRUs.keySet()) {
if (tu.getResource().exists()) {
final ICProject cproject= tu.getCProject();
DeltaAnalyzer analyzer= changeMap.get(cproject);
if (analyzer == null) {
analyzer= new DeltaAnalyzer();
changeMap.put(cproject, analyzer);
}
analyzer.getForcedList().add(tu);
}
analyzer.getForcedList().add(tu);
}
}
}
count= Math.min(count, newLRUs.length);
for (int i = 0; i < count; i++) {
final ITranslationUnit tu = newLRUs[i];
fLRUs.put(tu, tu);
count= Math.min(count, newLRUs.length);
for (int i = 0; i < count; i++) {
final ITranslationUnit tu = newLRUs[i];
fLRUs.put(tu, tu);
}
}
}
}