diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index ac45ebf2912..b4ccaec3a2d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) * Thomas Corbat (IFS) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -145,7 +146,12 @@ public class CPPClassSpecialization extends CPPSpecialization private ICPPClassSpecializationScope specScope; private ObjectMap specializationMap= ObjectMap.EMPTY_MAP; - private final ThreadLocal> fInProgress= new ThreadLocal>(); + private final ThreadLocal> fInProgress= new ThreadLocal>() { + @Override + protected Set initialValue() { + return new HashSet(); + } + }; public CPPClassSpecialization(ICPPClassType specialized, IBinding owner, ICPPTemplateParameterMap argumentMap) { @@ -164,23 +170,24 @@ public class CPPClassSpecialization extends CPPSpecialization @Override public IBinding specializeMember(IBinding original, IASTNode point) { - Set set; synchronized (this) { IBinding result= (IBinding) specializationMap.get(original); if (result != null) return result; - set= fInProgress.get(); - if (set == null) { - set= new HashSet(); - fInProgress.set(set); - } - if (!set.add(original)) - return RecursionResolvingBinding.createFor(original, point); } - IBinding result= CPPTemplates.createSpecialization(this, original, point); - set.remove(original); + IBinding result; + Set recursionProtectionSet= fInProgress.get(); + try { + if (!recursionProtectionSet.add(original)) + return RecursionResolvingBinding.createFor(original, point); + + result= CPPTemplates.createSpecialization(this, original, point); + } finally { + recursionProtectionSet.remove(original); + } + synchronized (this) { IBinding concurrent= (IBinding) specializationMap.get(original); if (concurrent != null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java index 1bbe094e1a9..040e3868534 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 Symbian Software Systems and others. + * Copyright (c) 2007, 2013 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -42,7 +42,12 @@ import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; public class CompositeCPPClassSpecialization extends CompositeCPPClassType implements ICPPClassSpecialization { private ObjectMap specializationMap; - private final ThreadLocal> fInProgress= new ThreadLocal>(); + private final ThreadLocal> fInProgress= new ThreadLocal>() { + @Override + protected Set initialValue() { + return new HashSet(); + } + }; public CompositeCPPClassSpecialization(ICompositesFactory cf, ICPPClassType rbinding) { super(cf, rbinding); @@ -103,21 +108,22 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple specializationMap= (ObjectMap) frag.putCachedResult(key, newMap, false); } } - Set set; synchronized (specializationMap) { IBinding result= (IBinding) specializationMap.get(original); if (result != null) return result; - set= fInProgress.get(); - if (set == null) { - set= new HashSet(); - fInProgress.set(set); - } - if (!set.add(original)) - return RecursionResolvingBinding.createFor(original, point); } - IBinding newSpec= CPPTemplates.createSpecialization(this, original, point); - set.remove(original); + + IBinding newSpec; + Set recursionProtectionSet= fInProgress.get(); + try { + if (!recursionProtectionSet.add(original)) + return RecursionResolvingBinding.createFor(original, point); + + newSpec= CPPTemplates.createSpecialization(this, original, point); + } finally { + recursionProtectionSet.remove(original); + } synchronized (specializationMap) { IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java index ef49d0f9182..354fa48f920 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java @@ -14,6 +14,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -44,12 +50,6 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - /** * @author Bryan Wilkinson */ @@ -67,7 +67,12 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements private volatile ICPPClassScope fScope; private ObjectMap specializationMap; // Obtained from the synchronized PDOM cache - private final ThreadLocal> fInProgress= new ThreadLocal>(); + private final ThreadLocal> fInProgress= new ThreadLocal>() { + @Override + protected Set initialValue() { + return new HashSet(); + } + }; public PDOMCPPClassSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType, PDOMBinding specialized) throws CoreException { @@ -132,21 +137,22 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements specializationMap= (ObjectMap) getPDOM().putCachedResult(key, newMap, false); } } - Set set; synchronized (specializationMap) { IBinding result= (IBinding) specializationMap.get(original); if (result != null) return result; - set= fInProgress.get(); - if (set == null) { - set= new HashSet(); - fInProgress.set(set); - } - if (!set.add(original)) - return RecursionResolvingBinding.createFor(original, point); } - IBinding newSpec= CPPTemplates.createSpecialization(this, original, point); - set.remove(original); + + IBinding newSpec; + Set recursionProtectionSet= fInProgress.get(); + try { + if (!recursionProtectionSet.add(original)) + return RecursionResolvingBinding.createFor(original, point); + + newSpec= CPPTemplates.createSpecialization(this, original, point); + } finally { + recursionProtectionSet.remove(original); + } synchronized (specializationMap) { IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec);