diff options
author | Ed Merks | 2013-01-07 16:30:50 +0000 |
---|---|---|
committer | Ed Merks | 2013-01-07 17:13:26 +0000 |
commit | 905ecc8cd506753b8f2e54f4868a50a9a9551700 (patch) | |
tree | 59ff978bc07377e5fe7f14b2abd43b03ecb8b0c7 | |
parent | 3378ca9013af9a81e0c9252ffb6a355cad9bedd1 (diff) | |
download | org.eclipse.emf-905ecc8cd506753b8f2e54f4868a50a9a9551700.tar.gz org.eclipse.emf-905ecc8cd506753b8f2e54f4868a50a9a9551700.tar.xz org.eclipse.emf-905ecc8cd506753b8f2e54f4868a50a9a9551700.zip |
[397171] Avoid leaky thread locals.
-rw-r--r-- | plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EClassImpl.java | 20 | ||||
-rw-r--r-- | plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/xml/type/util/XMLTypeUtil.java | 74 |
2 files changed, 70 insertions, 24 deletions
diff --git a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EClassImpl.java b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EClassImpl.java index b64757a51..0df702487 100644 --- a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EClassImpl.java +++ b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/impl/EClassImpl.java @@ -510,6 +510,10 @@ public class EClassImpl extends EClassifierImpl implements EClass, ESuperAdapter result.add(eGenericSuperType); } computationInProgress.remove(this); + if (computationInProgress.isEmpty()) + { + COMPUTATION_IN_PROGRESS.remove(); + } } result.eliminateEquivalentDuplicates(); @@ -583,6 +587,10 @@ public class EClassImpl extends EClassifierImpl implements EClass, ESuperAdapter result.addAll(eSuperType.getEAllAttributes()); } computationInProgress.remove(this); + if (computationInProgress.isEmpty()) + { + COMPUTATION_IN_PROGRESS.remove(); + } } for (EStructuralFeature eStructuralFeature : getEStructuralFeatures()) { @@ -661,6 +669,10 @@ public class EClassImpl extends EClassifierImpl implements EClass, ESuperAdapter result.addAll(eSuperType.getEAllReferences()); } computationInProgress.remove(this); + if (computationInProgress.isEmpty()) + { + COMPUTATION_IN_PROGRESS.remove(); + } } for (EStructuralFeature eStructuralFeature : getEStructuralFeatures()) { @@ -768,6 +780,10 @@ public class EClassImpl extends EClassifierImpl implements EClass, ESuperAdapter result.addAll(eSuperType.getEAllStructuralFeatures()); } computationInProgress.remove(this); + if (computationInProgress.isEmpty()) + { + COMPUTATION_IN_PROGRESS.remove(); + } } int featureID = result.size(); for (Iterator<EStructuralFeature> i = getEStructuralFeatures().iterator(); i.hasNext(); ++featureID) @@ -939,6 +955,10 @@ public class EClassImpl extends EClassifierImpl implements EClass, ESuperAdapter result.addAll(eSuperType.getEAllOperations()); } computationInProgress.remove(this); + if (computationInProgress.isEmpty()) + { + COMPUTATION_IN_PROGRESS.remove(); + } } int operationID = result.size(); for (Iterator<EOperation> i = getEOperations().iterator(); i.hasNext(); ++operationID) diff --git a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/xml/type/util/XMLTypeUtil.java b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/xml/type/util/XMLTypeUtil.java index a7e6877b5..2e79c163f 100644 --- a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/xml/type/util/XMLTypeUtil.java +++ b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/xml/type/util/XMLTypeUtil.java @@ -11,6 +11,8 @@ package org.eclipse.emf.ecore.xml.type.util; +import java.util.concurrent.atomic.AtomicReference; + import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; @@ -83,10 +85,9 @@ public final class XMLTypeUtil return DataValue.XMLChar.isSpace(value); } - // TODO // This is faster than many charAt() calls. // - private static class CharArrayThreadLocal extends ThreadLocal<char[]> + private static final class CharArrayPool { private static final int MAX_CACHE_CAPACITY; static @@ -109,38 +110,59 @@ public final class XMLTypeUtil MAX_CACHE_CAPACITY = result; } - private long cachedThread = -1; - private char [] cachedResult; - - public final char [] get(int capacity) + private class Buffer { - if (capacity > MAX_CACHE_CAPACITY) - { - return new char [capacity]; - } - long currentThread = Thread.currentThread().getId(); - char [] result = cachedResult; - if (cachedThread != currentThread) + Buffer next; + char[] value; + + public char[] get(int capacity) { - cachedThread = currentThread; - result = get(); + if (value == null || value.length < capacity) + { + value = new char [capacity < 20 ? 20 : capacity]; + } + return value; } - if (result.length < capacity) + + public void finished() { - result = new char [capacity]; - set(result); + if (value.length <= MAX_CACHE_CAPACITY) + { + for (;;) + { + next = head.get(); + if (head.compareAndSet(next, this)) + { + break; + } + } + } } - return cachedResult = result; } - @Override - protected char [] initialValue() + private AtomicReference<Buffer> head = new AtomicReference<Buffer>(); + + public Buffer get() { - return new char [20]; + for (;;) + { + Buffer buffer = head.get(); + if (buffer != null) + { + if (head.compareAndSet(buffer, buffer.next)) + { + return buffer; + } + } + else + { + return new Buffer(); + } + } } } - private static final CharArrayThreadLocal VALUE = new CharArrayThreadLocal(); + private static final CharArrayPool VALUE = new CharArrayPool(); public static String normalize(String value, boolean collapse) { @@ -155,7 +177,9 @@ public final class XMLTypeUtil return ""; } - char [] valueArray = VALUE.get(length); + CharArrayPool.Buffer pooledBuffer = VALUE.get(); + + char [] valueArray = pooledBuffer.get(length); value.getChars(0, length, valueArray, 0); StringBuffer buffer = null; boolean skipSpace = collapse; @@ -191,6 +215,8 @@ public final class XMLTypeUtil } } + pooledBuffer.finished(); + if (skipSpace) { if (buffer == null) |