Methods Summary |
---|
public synchronized void | connect(long timeout)
try {
switch (state) {
case 0:
break;
case 3:
return; // already connected
case 4:
state = 0;
throw new TransportException( "Connection in error", te );
default:
TransportException te = new TransportException( "Invalid state: " + state );
state = 0;
throw te;
}
state = 1;
te = null;
thread = new Thread( this, name );
thread.setDaemon( true );
synchronized (thread) {
thread.start();
thread.wait( timeout ); /* wait for doConnect */
switch (state) {
case 1: /* doConnect never returned */
state = 0;
thread = null;
throw new TransportException( "Connection timeout" );
case 2:
if (te != null) { /* doConnect throw Exception */
state = 4; /* error */
thread = null;
throw te;
}
state = 3; /* Success! */
return;
}
}
} catch( InterruptedException ie ) {
state = 0;
thread = null;
throw new TransportException( ie );
} finally {
/* This guarantees that we leave in a valid state
*/
if (state != 0 && state != 3 && state != 4) {
if (log.level >= 1)
log.println("Invalid state: " + state);
state = 0;
thread = null;
}
}
|
public synchronized void | disconnect(boolean hard)
IOException ioe = null;
switch (state) {
case 0: /* not connected - just return */
return;
case 2:
hard = true;
case 3: /* connected - go ahead and disconnect */
if (response_map.size() != 0 && !hard) {
break; /* outstanding requests */
}
try {
doDisconnect( hard );
} catch (IOException ioe0) {
ioe = ioe0;
}
case 4: /* in error - reset the transport */
thread = null;
state = 0;
break;
default:
if (log.level >= 1)
log.println("Invalid state: " + state);
thread = null;
state = 0;
break;
}
if (ioe != null)
throw ioe;
|
protected abstract void | doConnect()
|
protected abstract void | doDisconnect(boolean hard)
|
protected abstract void | doRecv(Response response)
|
protected abstract void | doSend(Request request)
|
protected abstract void | doSkip()
|
private void | loop()
while( thread == Thread.currentThread() ) {
try {
Request key = peekKey();
if (key == null)
throw new IOException( "end of stream" );
synchronized (this) {
Response response = (Response)response_map.get( key );
if (response == null) {
if (log.level >= 4)
log.println( "Invalid key, skipping message" );
doSkip();
} else {
doRecv( response );
response.isReceived = true;
notifyAll();
}
}
} catch( Exception ex ) {
String msg = ex.getMessage();
boolean timeout = msg != null && msg.equals( "Read timed out" );
/* If just a timeout, try to disconnect gracefully
*/
boolean hard = timeout == false;
if (!timeout && log.level >= 3)
ex.printStackTrace( log );
try {
disconnect( hard );
} catch( IOException ioe ) {
ioe.printStackTrace( log );
}
}
}
|
protected abstract void | makeKey(Request request)
|
protected abstract Request | peekKey()
|
public static int | readn(java.io.InputStream in, byte[] b, int off, int len)
int i = 0, n = -5;
while (i < len) {
n = in.read( b, off + i, len - i );
if (n <= 0) {
break;
}
i += n;
}
return i;
|
public void | run()
Thread run_thread = Thread.currentThread();
Exception ex0 = null;
try {
/* We cannot synchronize (run_thread) here or the caller's
* thread.wait( timeout ) cannot reaquire the lock and
* return which would render the timeout effectively useless.
*/
doConnect();
} catch( Exception ex ) {
ex0 = ex; // Defer to below where we're locked
return;
} finally {
synchronized (run_thread) {
if (run_thread != thread) {
/* Thread no longer the one setup for this transport --
* doConnect returned too late, just ignore.
*/
if (ex0 != null) {
if (log.level >= 2)
ex0.printStackTrace(log);
}
return;
}
if (ex0 != null) {
te = new TransportException( ex0 );
}
state = 2; // run connected
run_thread.notify();
}
}
/* Proccess responses
*/
loop();
|
public synchronized void | sendrecv(Request request, Response response, long timeout)
makeKey( request );
response.isReceived = false;
try {
response_map.put( request, response );
doSend( request );
response.expiration = System.currentTimeMillis() + timeout;
while (!response.isReceived) {
wait( timeout );
timeout = response.expiration - System.currentTimeMillis();
if (timeout <= 0) {
throw new TransportException( name +
" timedout waiting for response to " +
request );
}
}
} catch( IOException ioe ) {
if (log.level > 2)
ioe.printStackTrace( log );
try {
disconnect( true );
} catch( IOException ioe2 ) {
ioe2.printStackTrace( log );
}
throw ioe;
} catch( InterruptedException ie ) {
throw new TransportException( ie );
} finally {
response_map.remove( request );
}
|
public java.lang.String | toString()
return name;
|