public static void handleKey ( SelectionKey key ) { ConnectionHandler handler = ( ( ConnectionHandler ) key . attachment ( ) ) ; try { if ( handler == null ) return ; if ( ! key . isValid ( ) ) { handler . closeConnection ( ) ; // Key has been cancelled, make sure the socket gets closed return ; } if ( key . isReadable ( ) ) { // Do a socket read and invoke the connection's receiveBytes message int read = handler . channel . read ( handler . readBuff ) ; if ( read == 0 ) return ; // Was probably waiting on a write else if ( read == - 1 ) { // Socket was closed key . cancel ( ) ; handler . closeConnection ( ) ; return ; } // "flip" the buffer - setting the limit to the current position and setting position to 0 handler . readBuff . flip ( ) ; // Use connection.receiveBytes's return value as a check that it stopped reading at the right location int bytesConsumed = checkNotNull ( handler . connection ) . receiveBytes ( handler . readBuff ) ; checkState ( handler . readBuff . position ( ) == bytesConsumed ) ; // Now drop the bytes which were read by compacting readBuff (resetting limit and keeping relative // position) handler . readBuff . compact ( ) ; } if ( key . isWritable ( ) ) handler . tryWriteBytes ( ) ; } catch ( Exception e ) { // This can happen eg if the channel closes while the thread is about to get killed // (ClosedByInterruptException), or if handler.connection.receiveBytes throws something Throwable t = Throwables . getRootCause ( e ) ; log . warn ( "Error handling SelectionKey: {} {}" , t . getClass ( ) . getName ( ) , t . getMessage ( ) != null ? t . getMessage ( ) : "" , e ) ; handler . closeConnection ( ) ; } }
atomically for a given ConnectionHandler )