diff options
author | Marc Laukien <marc@zeroc.com> | 2003-12-08 20:19:04 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2003-12-08 20:19:04 +0000 |
commit | af36567995055c5e4182274ef0f18f7a5767c04d (patch) | |
tree | 738efc51534b86497561b899154b3efd6a339123 /java/src/IceInternal/Connection.java | |
parent | Winsock fix (diff) | |
download | ice-af36567995055c5e4182274ef0f18f7a5767c04d.tar.bz2 ice-af36567995055c5e4182274ef0f18f7a5767c04d.tar.xz ice-af36567995055c5e4182274ef0f18f7a5767c04d.zip |
deadlock fix
Diffstat (limited to 'java/src/IceInternal/Connection.java')
-rw-r--r-- | java/src/IceInternal/Connection.java | 73 |
1 files changed, 63 insertions, 10 deletions
diff --git a/java/src/IceInternal/Connection.java b/java/src/IceInternal/Connection.java index 7ae84a19121..1fdfc68d39b 100644 --- a/java/src/IceInternal/Connection.java +++ b/java/src/IceInternal/Connection.java @@ -1107,21 +1107,58 @@ public final class Connection extends EventHandler } } - public synchronized void + public void finished(ThreadPool threadPool) { - threadPool.promoteFollower(); - - if(_state == StateActive || _state == StateClosing) + IntMap requests = null; + IntMap asyncRequests = null; + + synchronized(this) + { + threadPool.promoteFollower(); + + if(_state == StateActive || _state == StateClosing) + { + registerWithPool(); + } + else if(_state == StateClosed && _transceiver != null) + { + _transceiver.close(); + _transceiver = null; + _threadPool = null; // We don't need the thread pool anymore. + notifyAll(); + } + + if(_state == StateClosed || _state == StateClosing) + { + requests = _requests; + _requests = new IntMap(); + + asyncRequests = _asyncRequests; + _asyncRequests = new IntMap(); + } + } + + if(requests != null) { - registerWithPool(); + java.util.Iterator i = requests.entryIterator(); + while(i.hasNext()) + { + IntMap.Entry e = (IntMap.Entry)i.next(); + Outgoing out = (Outgoing)e.getValue(); + out.finished(_exception); // Exception is immutable at this point. + } } - else if(_state == StateClosed && _transceiver != null) + + if(asyncRequests != null) { - _transceiver.close(); - _transceiver = null; - _threadPool = null; // We don't need the thread pool anymore. - notifyAll(); + java.util.Iterator i = asyncRequests.entryIterator(); + while(i.hasNext()) + { + IntMap.Entry e = (IntMap.Entry)i.next(); + OutgoingAsync out = (OutgoingAsync)e.getValue(); + out.__finished(_exception); // Exception is immutable at this point. + } } } @@ -1194,6 +1231,12 @@ public final class Connection extends EventHandler private void setState(int state, Ice.LocalException ex) { + // + // If setState() is called with an exception, then only closed + // and closing states are permissible. + // + assert(state == StateClosing || state == StateClosed); + if(_state == state) // Don't switch twice. { return; @@ -1226,6 +1269,15 @@ public final class Connection extends EventHandler // setState(state); + // + // We can't call __finished() on async requests here, because + // it's possible that the callback will trigger another call, + // which then might block on this connection. Calling + // finished() at this place works for non-async calls, but in + // order to keep the logic of sending exceptions to requests + // in one place, we don't do this here either. Instead, we + // move all the code into the finished() operation. + /* { java.util.Iterator i = _requests.entryIterator(); while(i.hasNext()) @@ -1247,6 +1299,7 @@ public final class Connection extends EventHandler } _asyncRequests.clear(); } + */ } private void |