summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2008-05-05 10:17:44 (EDT)
committerEike Stepper2008-05-05 10:17:44 (EDT)
commite434634d60e0424605b84d25c7fb125cdc82805b (patch)
tree69ce4954f92cd3c50073e55ec8d6f94ff5ef36ce
parent9bcfea3bd68e795cdb742fd30e4112535733376e (diff)
downloadcdo-e434634d60e0424605b84d25c7fb125cdc82805b.zip
cdo-e434634d60e0424605b84d25c7fb125cdc82805b.tar.gz
cdo-e434634d60e0424605b84d25c7fb125cdc82805b.tar.bz2
[230076] Client is hanging :-(
https://bugs.eclipse.org/bugs/show_bug.cgi?id=230076
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionDeadLockTest.java87
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/EMFUtil.java6
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/connector/Connector.java64
3 files changed, 90 insertions, 67 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionDeadLockTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionDeadLockTest.java
index 199ae32..0978163 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionDeadLockTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionDeadLockTest.java
@@ -22,6 +22,8 @@ import org.eclipse.net4j.util.om.OMPlatform;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
/**
* @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=213782
@@ -88,54 +90,68 @@ public class TransactionDeadLockTest extends AbstractCDOTest
public void testCreateManySessionTransactionMultiThread() throws Exception
{
- final ArrayList<Exception> exceptions = new ArrayList<Exception>();
- Runnable threadA = new Runnable()
+ final List<Exception> exceptions = new ArrayList<Exception>();
+ List<Thread> threadList = new ArrayList<Thread>();
+ for (int i = 0; i < 5; i++)
{
- public void run()
+ final int id = i;
+ threadList.add(new Thread(new Runnable()
{
- try
+ public void run()
{
- msg("Thread Starting");
- for (int i = 0; i < 100; i++)
+ try
{
- CDOSession session = openModel1Session();
- CDOTransaction transaction = session.openTransaction(new ResourceSetImpl());
-
- msg("Session + Transaction " + i);
- transaction.close();
- session.close();
+ msg("Thread " + id + ": Starting");
+ for (int i = 0; i < 100; i++)
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction(new ResourceSetImpl());
+
+ msg("Thread " + id + ": Session + Transaction " + i);
+ transaction.close();
+ session.close();
+ }
+
+ msg("Thread " + id + ": Done");
}
-
- msg("Thread done");
- }
- catch (Exception e)
- {
- synchronized (exceptions)
+ catch (Exception ex)
{
- exceptions.add(e);
+ synchronized (exceptions)
+ {
+ System.out.println("Thread " + id + ": " + ex.getClass().getName() + ": " + ex.getMessage());
+ exceptions.add(ex);
+ }
}
}
- }
- };
-
- ArrayList<Thread> threadList = new ArrayList<Thread>();
+ }));
+ }
- for (int i = 0; i < 5; i++)
+ startThreads(threadList);
+ for (Exception exp : exceptions)
{
- threadList.add(new Thread(threadA));
+ System.out.println();
+ System.out.println();
+ exp.printStackTrace();
+ System.out.println();
+ System.out.println();
}
- for (int i = 0; i < threadList.size(); i++)
+ assertEquals(0, exceptions.size());
+ }
+
+ private void startThreads(Collection<Thread> threadList)
+ {
+ for (Thread thread : threadList)
{
- threadList.get(i).start();
+ thread.start();
}
while (true)
{
int count = 0;
- for (int i = 0; i < threadList.size(); i++)
+ for (Thread thread : threadList)
{
- if (threadList.get(i).isAlive())
+ if (thread.isAlive())
{
break;
}
@@ -148,18 +164,7 @@ public class TransactionDeadLockTest extends AbstractCDOTest
break;
}
- sleep(1000);
+ sleep(100);
}
-
- for (Exception exp : exceptions)
- {
- System.out.println();
- System.out.println();
- exp.printStackTrace();
- System.out.println();
- System.out.println();
- }
-
- assertEquals(0, exceptions.size());
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/EMFUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/EMFUtil.java
index c2f0131..1b200da 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/EMFUtil.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/EMFUtil.java
@@ -304,7 +304,11 @@ public final class EMFUtil
{
URI uri = URI.createURI(ePackage.getNsURI());
Resource resource = resourceSet.createResource(uri);
- resource.getContents().add(ePackage);
+ synchronized (ePackage)
+ {
+ resource.getContents().add(ePackage);
+ }
+
return resource;
}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/connector/Connector.java b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/connector/Connector.java
index 12972e6..7b211dc 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/connector/Connector.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/connector/Connector.java
@@ -396,9 +396,8 @@ public abstract class Connector extends Container<IChannel> implements IConnecto
}
int channelID = getNextChannelID();
- short channelIndex = findFreeChannelIndex();
- InternalChannel channel = createChannel(channelID, channelIndex, protocol);
- registerChannelWithPeer(channelID, channelIndex, protocol);
+ InternalChannel channel = createChannel(channelID, protocol);
+ registerChannelWithPeer(channelID, channel.getChannelIndex(), protocol);
try
{
@@ -419,10 +418,10 @@ public abstract class Connector extends Container<IChannel> implements IConnecto
public InternalChannel createChannel(int channelID, short channelIndex, String protocolID)
{
IProtocol protocol = createProtocol(protocolID, null);
- return createChannel(channelID, channelIndex, protocol);
+ return createAndAddChannel(channelID, channelIndex, protocol);
}
- public InternalChannel createChannel(int channelID, short channelIndex, IProtocol protocol)
+ protected InternalChannel createChannelWithoutChannelIndex(int channelID, IProtocol protocol)
{
InternalChannel channel = createChannel();
channel.setChannelID(channelID);
@@ -434,21 +433,33 @@ public abstract class Connector extends Container<IChannel> implements IConnecto
if (TRACER.isEnabled())
{
String protocolType = protocol == null ? null : protocol.getType();
- TRACER.format("Opening channel {0} with protocol {1}", channelIndex, protocolType); //$NON-NLS-1$
+ TRACER.format("Opening channel ID {0} with protocol {1}", channelID, protocolType); //$NON-NLS-1$
}
}
else
{
if (TRACER.isEnabled())
{
- TRACER.format("Opening channel {0} without protocol", channelIndex); //$NON-NLS-1$
+ TRACER.format("Opening channel ID {0} without protocol", channelID); //$NON-NLS-1$
}
}
+ channel.setReceiveHandler(protocol);
+ channel.addListener(channelListener);
+ return channel;
+ }
+ public InternalChannel createAndAddChannel(int channelID, short channelIndex, IProtocol protocol)
+ {
+ InternalChannel channel = createChannelWithoutChannelIndex(channelID, protocol);
channel.setChannelIndex(channelIndex);
- channel.setReceiveHandler(protocol);
- channel.addListener(channelListener); // TODO remove?
- addChannel(channel);
+ addChannelWithIndex(channel);
+ return channel;
+ }
+
+ public InternalChannel createChannel(int channelID, IProtocol protocol)
+ {
+ InternalChannel channel = createChannelWithoutChannelIndex(channelID, protocol);
+ addChannelWithoutIndex(channel);
return channel;
}
@@ -476,39 +487,42 @@ public abstract class Connector extends Container<IChannel> implements IConnecto
return nextChannelID++;
}
- protected short findFreeChannelIndex()
+ protected void addChannelWithIndex(final InternalChannel channel)
{
- return channelsLock.read(new Callable<Short>()
+ channelsLock.write(new Runnable()
{
- public Short call() throws Exception
+ public void run()
{
- int size = channels.size();
- for (short i = 0; i < size; i++)
+ short channelIndex = channel.getChannelIndex();
+ while (channelIndex >= channels.size())
{
- if (channels.get(i) == null)
- {
- return i;
- }
+ channels.add(null);
}
- return (short)size;
+ channels.set(channelIndex, channel);
}
});
}
- protected void addChannel(final InternalChannel channel)
+ protected void addChannelWithoutIndex(final InternalChannel channel)
{
channelsLock.write(new Runnable()
{
public void run()
{
- short channelIndex = channel.getChannelIndex();
- while (channelIndex >= channels.size())
+ int size = channels.size();
+ for (short i = 0; i < size; i++)
{
- channels.add(null);
+ if (channels.get(i) == null)
+ {
+ channels.set(i, channel);
+ channel.setChannelIndex(i);
+ return;
+ }
}
- channels.set(channelIndex, channel);
+ channel.setChannelIndex((short)size);
+ channels.add(channel);
}
});
}