From e434634d60e0424605b84d25c7fb125cdc82805b Mon Sep 17 00:00:00 2001 From: Eike Stepper Date: Mon, 5 May 2008 14:17:44 +0000 Subject: [230076] Client is hanging :-( https://bugs.eclipse.org/bugs/show_bug.cgi?id=230076 --- .../emf/cdo/tests/TransactionDeadLockTest.java | 87 ++++++++++++---------- .../src/org/eclipse/emf/cdo/util/EMFUtil.java | 6 +- .../internal/net4j/connector/Connector.java | 64 +++++++++------- 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 199ae329c0..0978163f69 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 exceptions = new ArrayList(); - Runnable threadA = new Runnable() + final List exceptions = new ArrayList(); + List threadList = new ArrayList(); + 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 threadList = new ArrayList(); + })); + } - 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 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 c2f0131129..1b200dacf2 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 12972e629d..7b211dce8c 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 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 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 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 implements IConnecto return nextChannelID++; } - protected short findFreeChannelIndex() + protected void addChannelWithIndex(final InternalChannel channel) { - return channelsLock.read(new Callable() + 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); } }); } -- cgit v1.2.3