Author: david.lloyd(a)jboss.com
Date: 2008-02-21 11:08:55 -0500 (Thu, 21 Feb 2008)
New Revision: 3465
Modified:
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppConnection.java
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppProtocolSupport.java
remoting3/trunk/util/src/main/java/org/jboss/cx/remoting/core/util/AtomicStateMachine.java
Log:
Improve handling of errors on connect
Modified:
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppConnection.java
===================================================================
---
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppConnection.java 2008-02-21
15:38:16 UTC (rev 3464)
+++
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppConnection.java 2008-02-21
16:08:55 UTC (rev 3465)
@@ -77,6 +77,7 @@
private IoSession ioSession;
private String remoteName;
private ProtocolContext protocolContext;
+ private IOException failureReason;
/**
* The negotiated protocol version. Value is set to {@code min(PROTOCOL_VERSION,
remote PROTOCOL_VERSION)}.
@@ -106,6 +107,8 @@
UP,
/** Session is shutting down or closed */
CLOSED,
+ /** Session failed to connect */
+ FAILED,
}
private final AtomicStateMachine<State> state =
AtomicStateMachine.start(State.NEW);
@@ -336,11 +339,13 @@
output.commit();
}
- public boolean waitForUp() throws IOException {
- while (! state.in(State.UP, State.CLOSED)) {
+ public void waitForUp() throws IOException {
+ while (! state.in(State.UP, State.FAILED)) {
state.waitForAny();
}
- return state.in(State.UP);
+ if (state.in(State.FAILED)) {
+ throw failureReason;
+ }
}
private void close() {
@@ -349,6 +354,13 @@
protocolContext.closeSession();
}
+ private void fail(IOException reason) {
+ if (state.transitionExclusive(State.FAILED)) {
+ failureReason = reason;
+ state.releaseExclusive();
+ }
+ }
+
private static IoBuffer newBuffer(final int initialSize, final boolean autoexpand) {
return IoBuffer.allocate(initialSize + 4).setAutoExpand(autoexpand).skip(4);
}
@@ -589,7 +601,24 @@
}
public void sessionClosed() {
- close();
+ State current = state.getStateExclusive();
+ try {
+ switch (current) {
+ case AWAITING_CLIENT_AUTH_REQUEST:
+ case AWAITING_CLIENT_RESPONSE:
+ case AWAITING_CLIENT_VERSION:
+ case AWAITING_SERVER_CHALLENGE:
+ case AWAITING_SERVER_VERSION:
+ case NEW:
+ fail(new IOException("Unexpected session close"));
+ return;
+ default:
+ close();
+ return;
+ }
+ } finally {
+ state.releaseExclusive();
+ }
}
public void sessionIdle(IdleStatus idleStatus) {
@@ -597,7 +626,11 @@
public void exceptionCaught(Throwable throwable) {
log.error(throwable, "Exception from JRPP connection handler");
- close();
+ if (throwable instanceof IOException) {
+ fail((IOException)throwable);
+ } else {
+ fail(new IOException("Unexpected exception from handler: " +
throwable.toString()));
+ }
}
private ContextIdentifier readCtxtId(MessageInput input) throws IOException {
@@ -656,6 +689,7 @@
output.commit();
saslServerFilter.startEncryption(ioSession);
state.requireTransition(State.AWAITING_CLIENT_RESPONSE, State.UP);
+ protocolContext.openSession(remoteName);
}
} catch (SaslException ex) {
final IoBuffer buffer = newBuffer(100, true);
@@ -699,6 +733,7 @@
write(output, MessageType.AUTH_SUCCESS);
output.commit();
state.requireTransition(State.UP);
+ protocolContext.openSession(remoteName);
} else {
state.requireTransition(State.AWAITING_CLIENT_RESPONSE);
}
@@ -749,6 +784,7 @@
SaslClientFilter saslClientFilter = getSaslClientFilter();
saslClientFilter.startEncryption(ioSession);
state.requireTransition(State.AWAITING_SERVER_CHALLENGE,
State.UP);
+ protocolContext.openSession(remoteName);
return;
}
case AUTH_FAILED: {
Modified:
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppProtocolSupport.java
===================================================================
---
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppProtocolSupport.java 2008-02-21
15:38:16 UTC (rev 3464)
+++
remoting3/trunk/jrpp/src/main/java/org/jboss/cx/remoting/jrpp/JrppProtocolSupport.java 2008-02-21
16:08:55 UTC (rev 3465)
@@ -150,6 +150,7 @@
}
});
future.awaitUninterruptibly();
+ jrppConnection.waitForUp();
return jrppConnection.getProtocolHandler();
}
Modified:
remoting3/trunk/util/src/main/java/org/jboss/cx/remoting/core/util/AtomicStateMachine.java
===================================================================
---
remoting3/trunk/util/src/main/java/org/jboss/cx/remoting/core/util/AtomicStateMachine.java 2008-02-21
15:38:16 UTC (rev 3464)
+++
remoting3/trunk/util/src/main/java/org/jboss/cx/remoting/core/util/AtomicStateMachine.java 2008-02-21
16:08:55 UTC (rev 3465)
@@ -81,6 +81,19 @@
}
}
+ public boolean transitionExclusive(final T state) {
+ if (state == null) {
+ throw new NullPointerException("state is null");
+ }
+ writeLock.lock();
+ if (this.state == state) {
+ return false;
+ }
+ this.state = state;
+ cond.signalAll();
+ return true;
+ }
+
/**
* Release a held state. Must be called from the same thread that is holding the
state.
*/
Show replies by date