diff options
18 files changed, 253 insertions, 41 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java b/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java index 815f0c8e1b..1c57a3b36c 100644 --- a/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java @@ -12,6 +12,7 @@ package org.eclipse.net4j.tests; import org.eclipse.net4j.util.concurrent.ConcurrencyUtil; import org.eclipse.net4j.util.io.IOUtil; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.om.OMPlatform; import org.eclipse.net4j.util.om.log.PrintLogHandler; import org.eclipse.net4j.util.om.trace.PrintTraceHandler; @@ -117,4 +118,14 @@ public abstract class AbstractOMTest extends TestCase { ConcurrencyUtil.sleep(millis); } + + protected static void assertActive(Object object) + { + assertEquals(true, LifecycleUtil.isActive(object)); + } + + protected static void assertInactive(Object object) + { + assertEquals(false, LifecycleUtil.isActive(object)); + } } diff --git a/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPChannel.java b/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPChannel.java index 1ade346795..93530788ce 100644 --- a/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPChannel.java +++ b/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPChannel.java @@ -17,6 +17,7 @@ import org.eclipse.internal.net4j.channel.Channel; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * @author Eike Stepper @@ -72,11 +73,11 @@ public class HTTPChannel extends Channel openAck.countDown(); } - public void waitForOpenAck() + public void waitForOpenAck(long timeout) { try { - openAck.await(); + openAck.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException ignore) { diff --git a/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPConnector.java b/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPConnector.java index 8e1527762a..2a4d59a329 100644 --- a/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPConnector.java +++ b/plugins/org.eclipse.net4j.http.common/src/org/eclipse/net4j/http/internal/common/HTTPConnector.java @@ -189,14 +189,14 @@ public abstract class HTTPConnector extends Connector implements IHTTPConnector } @Override - protected void registerChannelWithPeer(final int channelID, final short channelIndex, final IProtocol protocol) - throws ConnectorException + protected void registerChannelWithPeer(final int channelID, final short channelIndex, final IProtocol protocol, + long timeout) throws ConnectorException { ChannelOperation operation = new OpenChannelOperation(channelIndex, channelID, protocol.getType()); outputOperations.add(operation); HTTPChannel channel = (HTTPChannel)getChannel(channelIndex); - channel.waitForOpenAck(); + channel.waitForOpenAck(timeout); } @Override diff --git a/plugins/org.eclipse.net4j.http.server/src/org/eclipse/net4j/http/internal/server/HTTPServerConnector.java b/plugins/org.eclipse.net4j.http.server/src/org/eclipse/net4j/http/internal/server/HTTPServerConnector.java index 1d26a5d1ad..9f007dc385 100644 --- a/plugins/org.eclipse.net4j.http.server/src/org/eclipse/net4j/http/internal/server/HTTPServerConnector.java +++ b/plugins/org.eclipse.net4j.http.server/src/org/eclipse/net4j/http/internal/server/HTTPServerConnector.java @@ -68,7 +68,7 @@ public class HTTPServerConnector extends HTTPConnector } @Override - protected void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol) + protected void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol, long timeout) throws ConnectorException { throw new UnsupportedOperationException(); diff --git a/plugins/org.eclipse.net4j.jvm/src/org/eclipse/net4j/internal/jvm/JVMConnector.java b/plugins/org.eclipse.net4j.jvm/src/org/eclipse/net4j/internal/jvm/JVMConnector.java index 8f3a83a58b..d3a665e179 100644 --- a/plugins/org.eclipse.net4j.jvm/src/org/eclipse/net4j/internal/jvm/JVMConnector.java +++ b/plugins/org.eclipse.net4j.jvm/src/org/eclipse/net4j/internal/jvm/JVMConnector.java @@ -113,7 +113,7 @@ public abstract class JVMConnector extends Connector implements IJVMConnector } @Override - protected void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol) + protected void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol, long timeoutIgnored) throws ConnectorException { try diff --git a/plugins/org.eclipse.net4j.tcp/.options b/plugins/org.eclipse.net4j.tcp/.options index 6dd14bc481..b985a44cd4 100644 --- a/plugins/org.eclipse.net4j.tcp/.options +++ b/plugins/org.eclipse.net4j.tcp/.options @@ -1,5 +1,3 @@ # Debugging and tracing options org.eclipse.net4j.tcp/debug = true - -org.eclipse.net4j.tcp/protocol.registration.timeout = 10000 diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ControlChannel.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ControlChannel.java index a1f62d868a..4297b91353 100644 --- a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ControlChannel.java +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ControlChannel.java @@ -31,10 +31,8 @@ import java.nio.ByteBuffer; /** * @author Eike Stepper */ -public final class ControlChannel extends Channel +public class ControlChannel extends Channel { - public static final long REGISTRATION_TIMEOUT = OM.PROTOCOL_REGISTRATION_TIMEOUT; - public static final short CONTROL_CHANNEL_INDEX = -1; public static final byte OPCODE_NEGOTIATION = 1; @@ -66,7 +64,7 @@ public final class ControlChannel extends Channel return (TCPConnector)getChannelMultiplexer(); } - public boolean registerChannel(int channelID, short channelIndex, IProtocol protocol) + public boolean registerChannel(int channelID, short channelIndex, IProtocol protocol, long timeout) { if (TRACER.isEnabled()) { @@ -84,10 +82,10 @@ public final class ControlChannel extends Channel BufferUtil.putUTF8(byteBuffer, protocol == null ? null : protocol.getType()); handleBuffer(buffer); - Boolean acknowledged = registration.get(REGISTRATION_TIMEOUT); + Boolean acknowledged = registration.get(timeout); if (acknowledged == null) { - throw new TimeoutRuntimeException("Registration timeout after " + REGISTRATION_TIMEOUT + " milliseconds"); + throw new TimeoutRuntimeException("Registration timeout after " + timeout + " milliseconds"); } return acknowledged; diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java index 9f82528b38..235e7356c2 100644 --- a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java @@ -180,7 +180,7 @@ public class TCPAcceptor extends Acceptor implements ITCPAcceptor, ITCPPassiveSe // socketChannel.socket().setKeepAlive(true); socketChannel.configureBlocking(false); - TCPServerConnector connector = new TCPServerConnector(this); + TCPServerConnector connector = createConnector(); prepareConnector(connector); connector.setSocketChannel(socketChannel); connector.setSelector(selector); @@ -248,4 +248,9 @@ public class TCPAcceptor extends Acceptor implements ITCPAcceptor, ITCPPassiveSe serverSocketChannel.close(); super.doDeactivate(); } + + protected TCPServerConnector createConnector() + { + return new TCPServerConnector(this); + } } diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPConnector.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPConnector.java index 1ef7eebed4..525141b85a 100644 --- a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPConnector.java +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPConnector.java @@ -276,12 +276,12 @@ public abstract class TCPConnector extends Connector implements ITCPConnector, I } @Override - protected void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol) + protected void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol, long timeout) throws ConnectorException { try { - if (!controlChannel.registerChannel(channelID, channelIndex, protocol)) + if (!controlChannel.registerChannel(channelID, channelIndex, protocol, timeout)) { throw new ConnectorException("Failed to register channel with peer"); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/OM.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/OM.java index 7600c05df5..0cafb3545f 100644 --- a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/OM.java +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/OM.java @@ -29,9 +29,6 @@ public abstract class OM public static final OMTracer DEBUG = BUNDLE.tracer("debug"); //$NON-NLS-1$ - public static final int PROTOCOL_REGISTRATION_TIMEOUT = BUNDLE.getDebugSupport().getDebugOption( - "protocol.registration.timeout", 10000); //$NON-NLS-1$ - public static final OMLogger LOG = BUNDLE.logger(); /** diff --git a/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF index 6b81dfefaa..c301a3d658 100644 --- a/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)", org.eclipse.net4j.jvm;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, org.junit;bundle-version="[3.8.0,4.0.0)";visibility:=reexport Export-Package: org.eclipse.net4j.tests;version="2.0.0", + org.eclipse.net4j.tests.bugzilla;version="2.0.0", org.eclipse.net4j.tests.bundle;version="2.0.0";x-internal:=true, org.eclipse.net4j.tests.signal;version="2.0.0", org.eclipse.net4j.util.tests;version="2.0.0", diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java index 35fd5d04bc..da25371f3a 100644 --- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java @@ -10,6 +10,7 @@ **************************************************************************/ package org.eclipse.net4j.tests; +import org.eclipse.net4j.tests.bugzilla.Bugzilla241463_Test; import org.eclipse.net4j.util.tests.ExtendedIOTest; import org.eclipse.net4j.util.tests.MonitorTest; import org.eclipse.net4j.util.tests.MultiMapTest; @@ -37,6 +38,7 @@ public class AllTests suite.addTestSuite(ReferenceValueMapTest.class); suite.addTestSuite(BufferPoolTest.class); suite.addTestSuite(ExtendedIOTest.class); + suite.addTestSuite(Bugzilla241463_Test.class); // suite.addTestSuite(SecurityTest.class); // TODO suite.addTestSuite(ConnectorTest.class); // $JUnit-END$ diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/bugzilla/Bugzilla241463_Test.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/bugzilla/Bugzilla241463_Test.java new file mode 100644 index 0000000000..b8e4aa1c25 --- /dev/null +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/bugzilla/Bugzilla241463_Test.java @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.tests.bugzilla; + +import org.eclipse.net4j.Net4jTransportInjector; +import org.eclipse.net4j.connector.IConnector; +import org.eclipse.net4j.internal.tcp.TCPAcceptor; +import org.eclipse.net4j.internal.tcp.TCPAcceptorFactory; +import org.eclipse.net4j.internal.tcp.TCPConnectorFactory; +import org.eclipse.net4j.internal.tcp.TCPSelectorFactory; +import org.eclipse.net4j.internal.tcp.TCPSelectorInjector; +import org.eclipse.net4j.internal.tcp.TCPServerConnector; +import org.eclipse.net4j.tcp.ITCPAcceptor; +import org.eclipse.net4j.tests.AbstractTransportTest; +import org.eclipse.net4j.tests.signal.TestSignalClientProtocolFactory; +import org.eclipse.net4j.tests.signal.TestSignalServerProtocolFactory; +import org.eclipse.net4j.util.ImplementationError; +import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException; +import org.eclipse.net4j.util.container.IManagedContainer; +import org.eclipse.net4j.util.container.ManagedContainer; +import org.eclipse.net4j.util.security.RandomizerFactory; + +import org.eclipse.internal.net4j.ExecutorServiceFactory; +import org.eclipse.internal.net4j.buffer.BufferProviderFactory; + +import org.eclipse.spi.net4j.InternalChannel; + +/** + * @author Eike Stepper + */ +public class Bugzilla241463_Test extends AbstractTransportTest +{ + @Override + protected IManagedContainer createContainer() + { + IManagedContainer container = new ManagedContainer(); + + // Net4j + container.registerFactory(new ExecutorServiceFactory()); + container.registerFactory(new BufferProviderFactory()); + container.registerFactory(new RandomizerFactory()); + container.addPostProcessor(new Net4jTransportInjector()); + + // TCP + container.registerFactory(new TCPSelectorFactory()); + container.registerFactory(new FakeAcceptorFactory()); + container.registerFactory(new TCPConnectorFactory()); + container.addPostProcessor(new TCPSelectorInjector()); + + // Test + container.registerFactory(new TestSignalServerProtocolFactory()); + container.registerFactory(new TestSignalClientProtocolFactory()); + return container; + } + + public void testBugzilla241463() throws Exception + { + startTransport(); + + IConnector connector = getConnector(); + connector.setOpenChannelTimeout(2000L); + + try + { + connector.openChannel(TestSignalClientProtocolFactory.TYPE, null); + fail("TimeoutRuntimeException expected"); + } + catch (TimeoutRuntimeException success) + { + } + catch (Throwable wrongException) + { + fail("TimeoutRuntimeException expected"); + } + } + + /** + * @author Eike Stepper + */ + private static final class FakeAcceptorFactory extends TCPAcceptorFactory + { + @Override + public TCPAcceptor create(String description) + { + TCPAcceptor acceptor = new TCPAcceptor() + { + @Override + protected TCPServerConnector createConnector() + { + return new TCPServerConnector(this) + { + @Override + public InternalChannel createChannel(int channelID, short channelIndex, String protocolID) + { + throw new ImplementationError("Simulated problem"); + } + }; + } + }; + + acceptor.setAddress(ITCPAcceptor.DEFAULT_ADDRESS); + acceptor.setPort(ITCPAcceptor.DEFAULT_PORT); + return acceptor; + } + } +} diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java index d6cc0785e2..e7fdb1a265 100644 --- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java @@ -12,6 +12,7 @@ package org.eclipse.net4j.util.tests; import org.eclipse.net4j.util.concurrent.ConcurrencyUtil; import org.eclipse.net4j.util.io.IOUtil; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.om.OMPlatform; import org.eclipse.net4j.util.om.log.PrintLogHandler; import org.eclipse.net4j.util.om.trace.PrintTraceHandler; @@ -119,4 +120,14 @@ public abstract class AbstractOMTest extends TestCase { ConcurrencyUtil.sleep(millis); } + + protected static void assertActive(Object object) + { + assertEquals(true, LifecycleUtil.isActive(object)); + } + + protected static void assertInactive(Object object) + { + assertEquals(false, LifecycleUtil.isActive(object)); + } } diff --git a/plugins/org.eclipse.net4j/.options b/plugins/org.eclipse.net4j/.options index 9d659517f5..f2bb0e447d 100644 --- a/plugins/org.eclipse.net4j/.options +++ b/plugins/org.eclipse.net4j/.options @@ -10,3 +10,4 @@ org.eclipse.net4j/debug.connector = true org.eclipse.net4j/debug.signal = true org.eclipse.net4j/set.signal.thread.name = false +org.eclipse.net4j/open.channel.timeout = 10000 diff --git a/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF index b9a8659fa1..6bd7652f40 100644 --- a/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF @@ -11,7 +11,14 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ClassPath: . Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)";resolution:=optional, org.eclipse.net4j.util;bundle-version="[2.0.0,3.0.0)";visibility:=reexport -Export-Package: org.eclipse.internal.net4j;version="2.0.0";x-internal:=true, +Export-Package: org.eclipse.internal.net4j;version="2.0.0"; + x-friends:="org.eclipse.net4j.http.server, + org.eclipse.net4j.jvm, + org.eclipse.net4j.tcp, + org.eclipse.net4j.http, + org.eclipse.net4j.http.common, + org.eclipse.net4j.http.tests, + org.eclipse.net4j.tests", org.eclipse.internal.net4j.acceptor;version="2.0.0"; x-friends:="org.eclipse.net4j.http.server, org.eclipse.net4j.jvm, @@ -20,7 +27,14 @@ Export-Package: org.eclipse.internal.net4j;version="2.0.0";x-internal:=true, org.eclipse.net4j.http.common, org.eclipse.net4j.http.tests, org.eclipse.net4j.tests", - org.eclipse.internal.net4j.buffer;version="2.0.0";x-friends:="org.eclipse.net4j.tcp", + org.eclipse.internal.net4j.buffer;version="2.0.0"; + x-friends:="org.eclipse.net4j.http.server, + org.eclipse.net4j.jvm, + org.eclipse.net4j.tcp, + org.eclipse.net4j.http, + org.eclipse.net4j.http.common, + org.eclipse.net4j.http.tests, + org.eclipse.net4j.tests", org.eclipse.internal.net4j.bundle;version="2.0.0";x-internal:=true, org.eclipse.internal.net4j.channel;version="2.0.0"; x-friends:="org.eclipse.net4j.http, @@ -47,4 +61,4 @@ Export-Package: org.eclipse.internal.net4j;version="2.0.0";x-internal:=true, org.eclipse.net4j.signal;version="2.0.0", org.eclipse.net4j.signal.failover;version="2.0.0", org.eclipse.net4j.signal.wrapping;version="2.0.0", - org.eclipse.spi.net4j + org.eclipse.spi.net4j;version="2.0.0" 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 b210ff5e46..fd0f21bb35 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 @@ -23,6 +23,7 @@ import org.eclipse.net4j.protocol.ServerProtocolFactory; import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.concurrent.RWLock; +import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException; import org.eclipse.net4j.util.container.Container; import org.eclipse.net4j.util.container.IContainer; import org.eclipse.net4j.util.container.IContainerEvent; @@ -83,13 +84,15 @@ public abstract class Connector extends Container<IChannel> implements InternalC */ private ExecutorService receiveExecutor; - private int nextChannelID; + private long openChannelTimeout = DEFAULT_OPEN_CHANNEL_TIMEOUT;; - private List<InternalChannel> channels = new ArrayList<InternalChannel>(0); + private transient int nextChannelID; - private RWLock channelsLock = new RWLock(2500); + private transient List<InternalChannel> channels = new ArrayList<InternalChannel>(0); - private ConnectorState connectorState = ConnectorState.DISCONNECTED; + private transient RWLock channelsLock = new RWLock(2500); + + private transient ConnectorState connectorState = ConnectorState.DISCONNECTED; /** * Is registered with each {@link IChannel} of this {@link IConnector}. @@ -166,6 +169,21 @@ public abstract class Connector extends Container<IChannel> implements InternalC return negotiationContext; } + public long getOpenChannelTimeout() + { + if (openChannelTimeout == DEFAULT_OPEN_CHANNEL_TIMEOUT) + { + return OM.BUNDLE.getDebugSupport().getDebugOption("open.channel.timeout", 10000); + } + + return openChannelTimeout; + } + + public void setOpenChannelTimeout(long openChannelTimeout) + { + this.openChannelTimeout = openChannelTimeout; + } + public boolean isClient() { return getLocation() == ConnectorLocation.CLIENT; @@ -389,22 +407,34 @@ public abstract class Connector extends Container<IChannel> implements InternalC return openChannel(protocol); } - public IChannel openChannel(IProtocol protocol) throws ConnectorException + public IChannel openChannel(final IProtocol protocol) throws ConnectorException { - if (!waitForConnection(Long.MAX_VALUE)) + long openChannelTimeout = getOpenChannelTimeout(); + long start = System.currentTimeMillis(); + if (!waitForConnection(openChannelTimeout)) { throw new ConnectorException("Connector not connected"); } + final long elapsed = System.currentTimeMillis() - start; int channelID = getNextChannelID(); InternalChannel channel = createChannel(channelID, protocol); - registerChannelWithPeer(channelID, channel.getChannelIndex(), protocol); try { + try + { + registerChannelWithPeer(channelID, channel.getChannelIndex(), protocol, openChannelTimeout - elapsed); + } + catch (TimeoutRuntimeException ex) + { + // Adjust the message for the complete timeout time + throw new TimeoutRuntimeException("Registration timeout after " + openChannelTimeout + " milliseconds"); + } + channel.activate(); } - catch (ConnectorException ex) + catch (RuntimeException ex) { throw ex; } @@ -444,6 +474,7 @@ public abstract class Connector extends Container<IChannel> implements InternalC TRACER.format("Opening channel ID {0} without protocol", channelID); //$NON-NLS-1$ } } + channel.setReceiveHandler(protocol); channel.addListener(channelListener); return channel; @@ -647,28 +678,33 @@ public abstract class Connector extends Container<IChannel> implements InternalC */ protected IProtocol createProtocol(String type, Object infraStructure) { - IRegistry<IFactoryKey, IFactory> registry = getProtocolFactoryRegistry(); - if (StringUtil.isEmpty(type) || registry == null) + if (StringUtil.isEmpty(type)) { return null; } + IRegistry<IFactoryKey, IFactory> registry = getProtocolFactoryRegistry(); + if (registry == null) + { + throw new ConnectorException("No protocol registry configured"); + } + // Get protocol factory IFactoryKey key = createProtocolFactoryKey(type); IFactory factory = registry.get(key); if (factory == null) { - if (TRACER.isEnabled()) - { - TRACER.trace("Unknown protocol " + type); //$NON-NLS-1$ - } - - return null; + throw new ConnectorException("Unknown protocol: " + type); //$NON-NLS-1$ } // Create protocol String description = null; IProtocol protocol = (IProtocol)factory.create(description); + if (protocol == null) + { + throw new ConnectorException("Invalid protocol factory: " + type); //$NON-NLS-1$ + } + protocol.setBufferProvider(bufferProvider); protocol.setExecutorService(receiveExecutor); if (infraStructure != null) @@ -761,7 +797,7 @@ public abstract class Connector extends Container<IChannel> implements InternalC super.doDeactivate(); } - protected abstract void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol) + protected abstract void registerChannelWithPeer(int channelID, short channelIndex, IProtocol protocol, long timeout) throws ConnectorException; /** diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/connector/IConnector.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/connector/IConnector.java index 078f1ca735..46d16b98c0 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/connector/IConnector.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/connector/IConnector.java @@ -55,6 +55,19 @@ import java.util.List; */ public interface IConnector extends IContainer<IChannel> { + /** + * @since 2.0 + */ + public static final long NO_OPEN_CHANNEL_TIMEOUT = Long.MAX_VALUE; + + /** + * Indicates to use the timeout that is configured via debug property <code>open.channel.timeout</code> (see .options + * file) which has a default of 10 seconds. + * + * @since 2.0 + */ + public static final long DEFAULT_OPEN_CHANNEL_TIMEOUT = -1L; + public String getURL(); /** @@ -163,4 +176,14 @@ public interface IConnector extends IContainer<IChannel> * @see #openChannel(String, Object) */ public IChannel openChannel(IProtocol protocol) throws ConnectorException; + + /** + * @since 2.0 + */ + public long getOpenChannelTimeout(); + + /** + * @since 2.0 + */ + public void setOpenChannelTimeout(long openChannelTimeout); } |