summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2009-12-28 06:30:08 (EST)
committerCaspar De Groot2009-12-28 06:30:08 (EST)
commite965454176c2d048d73db13aaa39f07fa055960d (patch)
tree28b40870e30a912594727dc9e86560215c1fbb79
parent6beb2d75b357cefb8c9ebe79129298f99aa6d512 (diff)
downloadcdo-e965454176c2d048d73db13aaa39f07fa055960d.zip
cdo-e965454176c2d048d73db13aaa39f07fa055960d.tar.gz
cdo-e965454176c2d048d73db13aaa39f07fa055960d.tar.bz2
[296087] [DB] AbstractMappingStrategy.createClassMapping can be invoked concurrently
https://bugs.eclipse.org/bugs/show_bug.cgi?id=296087
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java28
1 files changed, 18 insertions, 10 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
index fe3f238..aeae1c7 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
@@ -60,7 +60,7 @@ import java.util.Set;
/**
* This abstract base class implements those methods which are most likely common to most mapping strategies. It can be
* used to derive custom mapping strategy implementation.
- *
+ *
* @author Eike Stepper
* @since 2.0
*/
@@ -342,7 +342,6 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
private Set<IDBTable> getModelTables()
{
Set<IDBTable> tables = new HashSet<IDBTable>();
-
for (IClassMapping mapping : classMappings.values())
{
tables.addAll(mapping.getDBTables());
@@ -354,7 +353,6 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
private IClassMapping createClassMapping(EClass eClass)
{
IClassMapping mapping = doCreateClassMapping(eClass);
-
if (mapping != null)
{
classMappings.put(eClass, mapping);
@@ -372,16 +370,26 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
public final IClassMapping getClassMapping(EClass eClass)
{
+ // Try without synchronization first; this will almost always succeed, so it avoids the
+ // performance penalty of syncing in the majority of cases
IClassMapping result = classMappings.get(eClass);
- if (result != null)
- {
- return result;
- }
- else
+ if (result == null)
{
- // create class mapping on demand ...
- return createClassMapping(eClass);
+ // Synchronize on the classMappings to prevent concurrent invocations of createClassMapping
+ // (Synchronizing on the eClass allows for more concurrency, but is risky because application
+ // code may be syncing on the eClass also.)
+ synchronized (classMappings)
+ {
+ // Check again, because other thread may have just added the mapping
+ result = classMappings.get(eClass);
+ if (result == null)
+ {
+ result = createClassMapping(eClass);
+ }
+ }
}
+
+ return result;
}
public ITypeMapping createValueMapping(EStructuralFeature feature)