diff options
Diffstat (limited to 'java/src/Ice/ConnectionI.java')
-rw-r--r-- | java/src/Ice/ConnectionI.java | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/java/src/Ice/ConnectionI.java b/java/src/Ice/ConnectionI.java index 538950f53a8..ee57f415c01 100644 --- a/java/src/Ice/ConnectionI.java +++ b/java/src/Ice/ConnectionI.java @@ -184,6 +184,15 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne IceInternal.TraceUtil.traceHeader("received validate connection", is, _logger, _traceLevels); } } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + synchronized(this) + { + setState(StateClosed, ex.get()); + assert(_exception != null); + throw _exception; + } + } catch(LocalException ex) { synchronized(this) @@ -576,6 +585,44 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne _transceiver.write(stream, _endpoint.timeout()); } } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + synchronized(this) + { + setState(StateClosed, ex.get()); + assert(_exception != null); + + if(out != null) + { + // + // If the request has already been removed from + // the request map, we are out of luck. It would + // mean that finished() has been called already, + // and therefore the exception has been set using + // the Outgoing::finished() callback. In this + // case, we cannot throw the exception here, + // because we must not both raise an exception and + // have Outgoing::finished() called with an + // exception. This means that in some rare cases, + // a request will not be retried even though it + // could. But I honestly don't know how I could + // avoid this, without a very elaborate and + // complex design, which would be bad for + // performance. + // + IceInternal.Outgoing o = (IceInternal.Outgoing)_requests.remove(requestId); + if(o != null) + { + assert(o == out); + throw new IceInternal.LocalExceptionWrapper(_exception, ex.retry()); + } + } + else + { + throw new IceInternal.LocalExceptionWrapper(_exception, ex.retry()); + } + } + } catch(LocalException ex) { synchronized(this) @@ -686,6 +733,36 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne _transceiver.write(stream, _endpoint.timeout()); } } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + synchronized(this) + { + setState(StateClosed, ex.get()); + assert(_exception != null); + + // + // If the request has already been removed from the + // async request map, we are out of luck. It would + // mean that finished() has been called already, and + // therefore the exception has been set using the + // OutgoingAsync::__finished() callback. In this case, + // we cannot throw the exception here, because we must + // not both raise an exception and have + // OutgoingAsync::__finished() called with an + // exception. This means that in some rare cases, a + // request will not be retried even though it + // could. But I honestly don't know how I could avoid + // this, without a very elaborate and complex design, + // which would be bad for performance. + // + IceInternal.OutgoingAsync o = (IceInternal.OutgoingAsync)_asyncRequests.remove(requestId); + if(o != null) + { + assert(o == out); + throw new IceInternal.LocalExceptionWrapper(_exception, ex.retry()); + } + } + } catch(LocalException ex) { synchronized(this) @@ -882,6 +959,20 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne _transceiver.write(stream, _endpoint.timeout()); } } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + synchronized(this) + { + setState(StateClosed, ex.get()); + assert(_exception != null); + + // + // Since batch requests are all oneways (or datagrams), we + // must report the exception to the caller. + // + throw _exception; + } + } catch(LocalException ex) { synchronized(this) @@ -933,6 +1024,13 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne _transceiver.write(stream, _endpoint.timeout()); } } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + synchronized(this) + { + setState(StateClosed, ex.get()); + } + } catch(LocalException ex) { synchronized(this) @@ -962,6 +1060,10 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne _acmAbsoluteTimeoutMillis = System.currentTimeMillis() + _acmTimeout * 1000; } } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + setState(StateClosed, ex.get()); + } catch(LocalException ex) { setState(StateClosed, ex); @@ -986,6 +1088,10 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne initiateShutdown(); } } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + setState(StateClosed, ex.get()); + } catch(LocalException ex) { setState(StateClosed, ex); @@ -1620,6 +1726,10 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { initiateShutdown(); } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + setState(StateClosed, ex.get()); + } catch(LocalException ex) { setState(StateClosed, ex); @@ -1629,6 +1739,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne private void initiateShutdown() + throws IceInternal.LocalExceptionWrapper // Java-specific workaround in Transceiver.write(). { assert(_state == StateClosing); assert(_dispatchCount == 0); |