Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Merks2013-01-07 16:30:50 +0000
committerEd Merks2013-01-07 17:13:26 +0000
commit905ecc8cd506753b8f2e54f4868a50a9a9551700 (patch)
tree59ff978bc07377e5fe7f14b2abd43b03ecb8b0c7
parent3378ca9013af9a81e0c9252ffb6a355cad9bedd1 (diff)
downloadorg.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.java20
-rw-r--r--plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/xml/type/util/XMLTypeUtil.java74
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)

Back to the top