directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Niklas Therning <nik...@trillian.se>
Subject [mina] Bug in SocketIoProcessor.flush()
Date Tue, 25 Oct 2005 16:33:30 GMT
Hi,

While working on the traffic control implementation I stumbled across a
rather nasty bug. When the remote side of a connection has disconnected
ch.write() will throw an IOException in the following piece of code.
What I've found is that the that exception won't be propagated to the
caller (flushSessions()) which has a catch clause for IOException 
scheduling the session for removal.

for (;;)
{
  ...
  try
  {
    writtenBytes = ch.write( buf.buf() );
  }
  finally
  {
    ...
    if( buf.hasRemaining() )
    {
      ...
      break;
    }
    ...
  }
}

The reason why the exception isn't propagated is the break statement in
the finally block. The break causes the thrown IOException to be
discarded and the program counter will be positioned right after the end
of the for-loop. Since there are still unwritten bytes OP_WRITE will
remain on and the selector will wake up immediately on the next
iteration. The process will be repeated indefinitely and the CPU will be
on 100%.

This bug has probably never appeared before since OP_READ has always
been on. If OP_READ is on when the remote side disconnects
SocketIoProcessor.read() will handle the removal of the session.

This could be fixed by removing the try and finally statements around
this piece of code leaving:

for (;;)
{
  ...
  writtenBytes = ch.write( buf.buf() );
  ...
  if( buf.hasRemaining() )
  {
    ...
    break;
  }
  ...
}

I hope this made any sense! :) BTW: Should I have submitted this
directly to JIRA? Or do I need an account for that?
/Niklas


Mime
View raw message