Index: com/sun/grizzly/TCPConnectorHandler.java =================================================================== --- com/sun/grizzly/TCPConnectorHandler.java (revision 3404) +++ com/sun/grizzly/TCPConnectorHandler.java (working copy) @@ -131,75 +131,12 @@ protocol(Protocol.TCP); } - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the CallBackHandler. - * @param remoteAddress remote address to connect - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress, - CallbackHandler callbackHandler) throws IOException { - - connect(remoteAddress,null,callbackHandler); - } - /** * Connect to hostname:port. When an aysnchronous event happens (e.g * OP_READ or OP_WRITE), the {@link Controller} will invoke * the CallBackHandler. * @param remoteAddress remote address to connect - * @param localAddress local address to bind - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress, SocketAddress localAddress, - CallbackHandler callbackHandler) throws IOException { - - if (controller == null){ - throw new IllegalStateException("Controller cannot be null"); - } - - connect(remoteAddress,localAddress,callbackHandler, - (TCPSelectorHandler)controller.getSelectorHandler(protocol())); - } - - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the CallBackHandler. - * @param remoteAddress remote address to connect - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - * @param selectorHandler an instance of SelectorHandler. - * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress, - CallbackHandler callbackHandler, - TCPSelectorHandler selectorHandler) throws IOException { - - connect(remoteAddress,null,callbackHandler,selectorHandler); - } - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the CallBackHandler. - * @param remoteAddress remote address to connect * @param localAddress local address to bin * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when * a non blocking operation is ready to be handled. When null, all @@ -255,20 +192,6 @@ * Controller has been initialized. * @param remoteAddress remote address to connect * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress) - throws IOException { - connect(remoteAddress,(SocketAddress)null); - } - - - /** - * Connect to hostname:port. Internally an instance of Controller and - * its default SelectorHandler will be created everytime this method is - * called. This method should be used only and only if no external - * Controller has been initialized. - * @param remoteAddress remote address to connect - * @throws java.io.IOException * @param localAddress local address to bin */ public void connect(SocketAddress remoteAddress, SocketAddress localAddress) @@ -309,8 +232,7 @@ callbackHandler = new DefaultCallbackHandler(this); } - connect(remoteAddress,localAddress,callbackHandler, - (TCPSelectorHandler)controller.getSelectorHandler(protocol())); + connect(remoteAddress,localAddress,callbackHandler); } Index: com/sun/grizzly/ComplexSelectorHandler.java =================================================================== --- com/sun/grizzly/ComplexSelectorHandler.java (revision 3404) +++ com/sun/grizzly/ComplexSelectorHandler.java (working copy) @@ -54,5 +54,20 @@ * @param protocol Network protocol name * @return true if protocol is supported, false otherwise */ - public boolean supportsProtocol(Protocol protocol); + public boolean supportsProtocol(Protocol protocol); + + /** + * Checks if given {@link SelectorHandler} is supported on client-side by RoundRobinSelectorHandler + * + * @param selectorHandler {@link SelectorHandler} + * @return true if selectorHandler is supported, false otherwise + */ + public boolean supportsClient(SelectorHandler selectorHandler); + + /** + * Return next aux. ReadController to process an accepted connection + * + * @return next aux. {@link ReadController} + */ + public ReadController nextController(); } Index: com/sun/grizzly/RoundRobinSelectorHandler.java =================================================================== --- com/sun/grizzly/RoundRobinSelectorHandler.java (revision 3404) +++ com/sun/grizzly/RoundRobinSelectorHandler.java (working copy) @@ -43,6 +43,8 @@ import java.io.IOException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.CopyOnWriteArraySet; import java.util.Set; /** @@ -60,9 +62,9 @@ public class RoundRobinSelectorHandler extends TCPSelectorHandler implements ComplexSelectorHandler { private ReadController[] rrControllers; - private int roundRobinCounter; - private Set customProtocols; - + private AtomicInteger roundRobinCounter = new AtomicInteger(); + private Set customProtocols = new CopyOnWriteArraySet(); + public RoundRobinSelectorHandler() {} public RoundRobinSelectorHandler(ReadController[] rrControllers) { @@ -82,27 +84,27 @@ ReadController auxController = nextController(); SelectorHandler protocolSelectorHandler = context.getSelectorHandler(); SelectableChannel channel = protocolSelectorHandler.acceptWithoutRegistration(key); - + if (channel != null) { protocolSelectorHandler.configureChannel(channel); - SelectorHandler relativeSelectorHandler = + SelectorHandler relativeSelectorHandler = auxController.getSelectorHandlerClone(protocolSelectorHandler); - + if (relativeSelectorHandler == null) { // Clone was not found - take correspondent protocol SelectorHandler - relativeSelectorHandler = + relativeSelectorHandler = auxController.getSelectorHandler(protocolSelectorHandler.protocol()); if (relativeSelectorHandler == null) { throw new IOException("Can not get correct SelectorHandler"); } } - + auxController.addChannel(channel, relativeSelectorHandler); } return false; } - + /** * Add custom protocol support * @param customProtocol custom {@link Controller.Protocol} @@ -110,7 +112,7 @@ public void addProtocolSupport(Protocol customProtocol) { customProtocols.add(customProtocol); } - + /** * {@inheritDoc} */ @@ -118,12 +120,31 @@ return protocol == Protocol.TCP || protocol == Protocol.TLS || customProtocols.contains(protocol); } - + /** - * Return next aux. ReadController to process an accepted connection - * @return{@link ReadController} + * {@inheritDoc} */ - private ReadController nextController() { - return rrControllers[((roundRobinCounter++) & 0x7fffffff) % rrControllers.length]; + public boolean supportsClient( SelectorHandler selectorHandler ) { + if( selectorHandler == null ) + return false; + if( selectorHandler instanceof ReusableTCPSelectorHandler || + selectorHandler instanceof ReusableUDPSelectorHandler ) + return false; + Protocol protocol = selectorHandler.protocol(); + return protocol == Protocol.TCP || protocol == Protocol.TLS || + protocol == Protocol.UDP || customProtocols.contains( protocol ); } + + /** + * {@inheritDoc} + */ + public ReadController nextController() { + return rrControllers[(roundRobinCounter.incrementAndGet() & 0x7fffffff) % rrControllers.length]; + } + + @Override + public void shutdown() { + super.shutdown(); + customProtocols.clear(); + } } Index: com/sun/grizzly/UDPConnectorHandler.java =================================================================== --- com/sun/grizzly/UDPConnectorHandler.java (revision 3404) +++ com/sun/grizzly/UDPConnectorHandler.java (working copy) @@ -87,67 +87,6 @@ * OP_READ or OP_WRITE), the {@link Controller} will invoke * the CallBackHandler. * @param remoteAddress remote address to connect - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - */ - public void connect(SocketAddress remoteAddress, - CallbackHandler callbackHandler) throws IOException { - - connect(remoteAddress,null,callbackHandler); - } - - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the CallBackHandler. - * @param remoteAddress remote address to connect - * @param localAddress local address to bind - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - */ - public void connect(SocketAddress remoteAddress, SocketAddress localAddress, - CallbackHandler callbackHandler) throws IOException { - - if (controller == null){ - throw new IllegalStateException("Controller cannot be null"); - } - - connect(remoteAddress,localAddress,callbackHandler, - (UDPSelectorHandler)controller.getSelectorHandler(protocol())); - } - - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the CallBackHandler. - * @param remoteAddress remote address to connect - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - * @param selectorHandler an instance of SelectorHandler. - */ - public void connect(SocketAddress remoteAddress, - CallbackHandler callbackHandler, - UDPSelectorHandler selectorHandler) throws IOException { - - connect(remoteAddress,null,callbackHandler,selectorHandler); - } - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the CallBackHandler. - * @param remoteAddress remote address to connect * @param localAddress local address to bin * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when * a non blocking operation is ready to be handled. When null, all @@ -198,18 +137,6 @@ * called. This method should be used only and only if no external * Controller has been initialized. * @param remoteAddress remote address to connect - */ - public void connect(SocketAddress remoteAddress) throws IOException { - connect(remoteAddress,(SocketAddress)null); - } - - - /** - * Connect to hostname:port. Internally an instance of Controller and - * its default SelectorHandler will be created everytime this method is - * called. This method should be used only and only if no external - * Controller has been initialized. - * @param remoteAddress remote address to connect * @param localAddress local address to bin */ public void connect(SocketAddress remoteAddress, SocketAddress localAddress) @@ -245,8 +172,7 @@ } } - connect(remoteAddress,localAddress,callbackHandler, - (UDPSelectorHandler)controller.getSelectorHandler(protocol())); + connect(remoteAddress,localAddress,callbackHandler); } Index: com/sun/grizzly/SSLConnectorHandler.java =================================================================== --- com/sun/grizzly/SSLConnectorHandler.java (revision 3404) +++ com/sun/grizzly/SSLConnectorHandler.java (working copy) @@ -237,61 +237,6 @@ * OP_READ or OP_WRITE), the {@link Controller} will invoke * the {@link CallbackHandler}. * @param remoteAddress remote address to connect - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress, SSLCallbackHandler callbackHandler) throws IOException { - connect(remoteAddress, null, callbackHandler); - } - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the {@link CallbackHandler}. - * @param remoteAddress remote address to connect - * @param localAddress local address to bind - * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when - * a non blocking operation is ready to be handled. When null, all - * read and write operation will be delegated to the default - * {@link ProtocolChain} and its list of {@link ProtocolFilter} - * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. - * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress, SocketAddress localAddress, - SSLCallbackHandler callbackHandler) throws IOException { - if (controller == null) { - throw new IllegalStateException("Controller cannot be null"); - } - - connect(remoteAddress, localAddress, callbackHandler, - (SSLSelectorHandler) controller.getSelectorHandler(protocol())); - } - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the {@link CallbackHandler}. - * @param remoteAddress remote address to connect - * @param callbackHandler the handler invoked by the Controller when - * an non blocking operation is ready to be handled. - * @param selectorHandler an instance of SelectorHandler. - * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress, - SSLCallbackHandler callbackHandler, - SSLSelectorHandler selectorHandler) throws IOException { - connect(remoteAddress, null, callbackHandler, selectorHandler); - } - - /** - * Connect to hostname:port. When an aysnchronous event happens (e.g - * OP_READ or OP_WRITE), the {@link Controller} will invoke - * the {@link CallbackHandler}. - * @param remoteAddress remote address to connect * @param localAddress local address to bin * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when * a non blocking operation is ready to be handled. When null, all @@ -343,18 +288,6 @@ * Controller has been initialized. * @param remoteAddress remote address to connect * @throws java.io.IOException - */ - public void connect(SocketAddress remoteAddress) throws IOException { - connect(remoteAddress, (SocketAddress) null); - } - - /** - * Connect to hostname:port. Internally an instance of Controller and - * its default SelectorHandler will be created everytime this method is - * called. This method should be used only and only if no external - * Controller has been initialized. - * @param remoteAddress remote address to connect - * @throws java.io.IOException * @param localAddress local address to bin */ public void connect(SocketAddress remoteAddress, SocketAddress localAddress) @@ -393,8 +326,7 @@ } } - connect(remoteAddress, localAddress, callbackHandler, (SSLSelectorHandler) - controller.getSelectorHandler(protocol())); + connect(remoteAddress, localAddress, callbackHandler); } /** Index: com/sun/grizzly/AbstractConnectorHandler.java =================================================================== --- com/sun/grizzly/AbstractConnectorHandler.java (revision 3404) +++ com/sun/grizzly/AbstractConnectorHandler.java (working copy) @@ -146,6 +146,87 @@ } /** + * Connect to hostname:port. When an aysnchronous event happens (e.g + * OP_READ or OP_WRITE), the {@link Controller} will invoke + * the CallBackHandler. + * @param remoteAddress remote address to connect + * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when + * a non blocking operation is ready to be handled. When null, all + * read and write operation will be delegated to the default + * {@link ProtocolChain} and its list of {@link ProtocolFilter} + * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. + * @throws java.io.IOException + */ + public void connect(SocketAddress remoteAddress, K callbackHandler) throws IOException { + connect(remoteAddress,null,callbackHandler); + } + + /** + * Connect to hostname:port. Internally an instance of Controller and + * its default SelectorHandler will be created everytime this method is + * called. This method should be used only and only if no external + * Controller has been initialized. + * @param remoteAddress remote address to connect + * @throws java.io.IOException + */ + public void connect(SocketAddress remoteAddress) throws IOException { + connect(remoteAddress,(SocketAddress)null); + } + + /** + * Connect to hostname:port. When an aysnchronous event happens (e.g + * OP_READ or OP_WRITE), the {@link Controller} will invoke + * the CallBackHandler. + * @param remoteAddress remote address to connect + * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when + * a non blocking operation is ready to be handled. When null, all + * read and write operation will be delegated to the default + * {@link ProtocolChain} and its list of {@link ProtocolFilter} + * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. + * @param selectorHandler an instance of SelectorHandler. + * @throws java.io.IOException + */ + public void connect(SocketAddress remoteAddress, K callbackHandler, E selectorHandler) throws IOException { + connect(remoteAddress,null,callbackHandler,selectorHandler); + } + + /** + * Connect to hostname:port. When an aysnchronous event happens (e.g + * OP_READ or OP_WRITE), the {@link Controller} will invoke + * the CallBackHandler. + * @param remoteAddress remote address to connect + * @param localAddress local address to bind + * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when + * a non blocking operation is ready to be handled. When null, all + * read and write operation will be delegated to the default + * {@link ProtocolChain} and its list of {@link ProtocolFilter} + * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. + * @throws java.io.IOException + */ + @SuppressWarnings("unchecked") + public void connect(SocketAddress remoteAddress, SocketAddress localAddress, K callbackHandler) throws IOException { + if( controller == null ) + throw new IllegalStateException("Controller cannot be null"); + if( protocol == null ) + throw new IllegalStateException("Protocol cannot be null"); + SelectorHandler selectorHandler = controller.getSelectorHandler( protocol ); + if( controller.getReadThreadsCount() > 0 && + controller.multiReadThreadSelectorHandler.supportsClient( selectorHandler ) ) { + if( controller.multiReadThreadSelectorHandler == null ) + throw new IllegalStateException("ComplexSelectorHandler cannot be null"); + ReadController auxController = controller.multiReadThreadSelectorHandler.nextController(); + SelectorHandler relativeSelectorHandler = auxController.getSelectorHandlerClone( selectorHandler ); + if( relativeSelectorHandler == null ) { + relativeSelectorHandler = auxController.getSelectorHandler( selectorHandler.protocol() ); + if( relativeSelectorHandler == null ) + throw new IOException( "Can not get correct SelectorHandler" ); + } + selectorHandler = relativeSelectorHandler; + } + connect(remoteAddress, localAddress, callbackHandler, (E)selectorHandler); + } + + /** * Set the associated {@link SelectorHandler} * @param selectorHandler the associated {@link SelectorHandler}. */