" (timeout was " + timeout_unit.toMillis( timeout ) + ")" );
}
// NOTE: session won't be set in the container until after the VMID attribute
// is set, so it's safe to use this rather than the VMID future.
VMID session_vmid = ( VMID ) session.getAttribute( VMID_KEY );
assert session_vmid != null;
assert session_map.containsKey( session_vmid );
return session_vmid;
}
boolean abend = true;
try {
long remaining = timeout_unit.toNanos( timeout );
IOException exception = null;
connection_listener.connectionOpening( address, port, attachment, args,
connection_type_description );
boolean first = true;
while( first || ( keep_trying && remaining > 0 ) ) {
long start = System.nanoTime();
try {
if ( first ) first = false;
else {
// Wait a second.
if ( !ThreadKit.sleep( 1000 ) ) {
throw new InterruptedIOException();
}
}
for( int i = 0; i < 3; i++ ) {
try {
VMID vmid = inner_connect( address, port, args, null,
attachment, remaining, container, null );
if ( vmid != null ) {
abend = false;
return vmid;
}
break;
}
catch( IOException ex ) {
exception = ex;
// If the exception has a cause and it's an instance of
// MINA's RuntimeIoException, try again. This is trying to
// work around a problem in the JDK where this exception is
// received when setting keep alive and nodelay flags:
// Caused by: org.apache.mina.core.RuntimeIoException:
// java.net.SocketException: Invalid argument:
// no further information
// at ...NioSocketSession$SessionConfigImpl.setKeepAlive(NioSocketSession.java:133)
if ( ex.getCause() != null &&
ex.getCause() instanceof RuntimeIoException ) {
// continue
}
else break;
}
}
}
finally {
remaining -= System.nanoTime() - start;
if ( abend ) {
connection_listener.connectionOpenFailed( address, port,
attachment, exception, remaining > 0 );
}
}
}
if ( exception == null ) {
exception = new ConnectException( "Connect timed out: " + host_and_port );
}
throw exception;
}
catch ( InterruptedException e ) {
InterruptedIOException ex = new InterruptedIOException();
ex.initCause( e );
throw ex;
}
finally {
// If the connection failed, clean up the outbound_session_map
if ( abend ) {
map_lock.lock();
try {
SessionContainer pulled_container =
outbound_session_map.remove( host_and_port );
if ( pulled_container != null && pulled_container == container ) {
// Make sure it doesn't have a VMID, and clean up if it does
IoSession session = pulled_container.getSession();
if ( session != null ) {
CloseHandler.close( session );
VMID vmid = ( VMID ) session.getAttribute( VMID_KEY );
if ( vmid != null ) {
SessionContainer session_map_container =
session_map.remove( vmid );
if ( session_map_container != pulled_container ) {