Commit 1b2dd66e authored by Guus der Kinderen's avatar Guus der Kinderen

OF-883 & OF-881: Avoid potential deadlock with close listeners.

The close listeners should not be called from within a synchronized block.
parent c51067b8
...@@ -219,46 +219,52 @@ public class NIOConnection implements Connection { ...@@ -219,46 +219,52 @@ public class NIOConnection implements Connection {
return backupDeliverer; return backupDeliverer;
} }
public synchronized void close() public void close()
{ {
try boolean notifyClose = false;
{ synchronized ( this ) {
if ( state == State.CLOSED ) try
{ {
return; if ( state == State.CLOSED )
} {
return;
}
// This prevents any action after the first invocation of close() on this connection. // This prevents any action after the first invocation of close() on this connection.
if ( state != State.CLOSING ) if ( state != State.CLOSING )
{
state = State.CLOSING;
try
{ {
deliverRawText( flashClient ? "</flash:stream>" : "</stream:stream>" ); state = State.CLOSING;
try
{
deliverRawText( flashClient ? "</flash:stream>" : "</stream:stream>" );
}
catch ( Exception e )
{
// Ignore
}
} }
catch ( Exception e )
// deliverRawText might already have forced the state from Closing to Closed. In that case, there's no need
// to invoke the CloseListeners again.
if ( state == State.CLOSING )
{ {
// Ignore notifyClose = true;
} }
} }
finally
// deliverRawText might already have forced the state from Closing to Closed. In that case, there's no need
// to invoke the CloseListeners again.
if ( state == State.CLOSING )
{ {
// TODO Check for regression of OF-881 (which placed the call below outside of the synchronized block). // Ensure that the state of this connection, its session and the MINA context are eventually closed.
notifyCloseListeners(); // clean up session, etc. state = State.CLOSED;
if ( session != null )
{
session.setStatus( Session.STATUS_CLOSED );
}
ioSession.close( true );
} }
} }
finally if (notifyClose)
{ {
// Ensure that the state of this connection, its session and the MINA context are eventually closed. notifyCloseListeners(); // clean up session, etc.
state = State.CLOSED;
if ( session != null )
{
session.setStatus( Session.STATUS_CLOSED );
}
ioSession.close( true );
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment