result = e;
}
}
else
{
SelectionKey selKey = null;
boolean error = false;
try
{
if ( this._channel == null || !this._channel.isOpen() )
{
log.log( Level.FINEST, "opening new connection" );
openSocketChannel();
_channel.register( this._selector, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE );
}
else
{
log.log( Level.FINEST, "reusing persistent connection" );
selKey = _channel.keyFor( this._selector );
// register this channel again
selKey = _channel.register( this._selector, 0 );
selKey.interestOps( SelectionKey.OP_WRITE );
}
Iterator it = null;
while ( this._selector.select( _connectionTimeout ) > 0 )
{
it = this._selector.selectedKeys().iterator();
while ( it.hasNext() )
{
selKey = (SelectionKey) it.next();
it.remove();
if ( !selKey.isValid() )
{
continue;
}
try
{
if ( selKey.isConnectable() && _channel.isConnectionPending() )
{
if ( !_channel.finishConnect() )
{
continue;
}
clientInfo.setChannel( _channel );
if ( log.isLoggable( Level.INFO ) )
{
log.log( Level.INFO, "Connection established to "
+ _channel.socket().getRemoteSocketAddress() );
}
_channel.register( this._selector, SelectionKey.OP_WRITE );
}
if ( selKey.isWritable() )
{
if ( _serverInfo == null )
{
log.log( Level.FINEST, "Handshaking server..." );
_serverInfo = DataChannel.getInstance().handshake( clientInfo, _channel,
_connectionTimeout );
if ( _serverInfo == null )
{
throw new IOException( "Connection timeout (" + _connectionTimeout
+ "ms) reached while waiting for handshake completing." );
}
else if ( clientInfo.isHttp() && !_serverInfo.isHttp() )
{
throw new UnsupportedOperationException(
"The server does not permit usage of HTTP packaging!" );
}
}
if ( _serverInfo.hasNonBlockingReadWrite() )
{
send( _serverInfo, clientInfo, selKey, obj );
_channel.register( this._selector, SelectionKey.OP_READ );
}
else
{
selKey.cancel();
_channel.configureBlocking( true );
result = processBlocked( clientInfo, obj );
if ( result != null && (result instanceof Throwable) )
{
if ( !(result instanceof RemoteException) )
{
throw new RemoteException(
"The server did return an Exception while handling your request!",
(Throwable) result );
}
else
{
throw (RemoteException) result;
}
}
return result;
}
}
else if ( selKey.isReadable() )
{
result = receive( clientInfo );
selKey.cancel();
if ( result != null && (result instanceof Throwable) )
{
if ( !(result instanceof RemoteException) )
{
throw new RemoteException(
"The server did return an Exception while handling your request!",
(Throwable) result );
}
else
{
throw (RemoteException) result;
}
}
return result;
}
}
catch ( IncompleteIOException ioe )
{
// selKey.cancel();
if ( ioe.getIOBuffer() != null )
{
clientInfo.setWaitingBuffer( ioe.getIOBuffer() );
_channel.register( this._selector, ioe.getSelectionInterest() );
}
else
{
// rethrow origin exception to inform the caller
// without the hassle of nested exceptions
throw ioe;
}
}
catch ( ParseException e )
{
error = true;
throw new IOException(
"Connection closed due to unparseable connection header! Exact message was: "
+ e.getMessage() );
}
catch ( IOException e )
{
if ( !(e instanceof RemoteException) )
{
error = true;
}
// rethrow origin exception to inform the caller
// without the hassle of nested exceptions
throw e;
}
}
}
}
finally
{
selKey.cancel();
// beeing a little bit paranoid is sometimes better
clientInfo.releaseAttachment();
clientInfo.releaseWaitingBuffer();
if ( _serverInfo != null )
{