@Override public void in_event() { // If still handshaking, receive and process the greeting message. if (handshaking) if (!handshake()) return; assert (decoder != null); boolean disconnection = false; // If there's no data to process in the buffer... if (insize == 0) { // Retrieve the buffer and read as much data as possible. // Note that buffer can be arbitrarily large. However, we assume // the underlying TCP layer has fixed buffer size and thus the // number of bytes read will be always limited. inbuf = decoder.get_buffer(); insize = read(inbuf); inbuf.flip(); // Check whether the peer has closed the connection. if (insize == -1) { insize = 0; disconnection = true; } } // Push the data to the decoder. int processed = decoder.process_buffer(inbuf, insize); if (processed == -1) { disconnection = true; } else { // Stop polling for input if we got stuck. if (processed < insize) io_object.reset_pollin(handle); // Adjust the buffer. insize -= processed; } // Flush all messages the decoder may have produced. session.flush(); // An input error has occurred. If the last decoded message // has already been accepted, we terminate the engine immediately. // Otherwise, we stop waiting for socket events and postpone // the termination until after the message is accepted. if (disconnection) { if (decoder.stalled()) { io_object.rm_fd(handle); io_enabled = false; } else error(); } }
@Override public void activate_in() { if (!io_enabled) { // There was an input error but the engine could not // be terminated (due to the stalled decoder). // Flush the pending message and terminate the engine now. decoder.process_buffer(inbuf, 0); assert (!decoder.stalled()); session.flush(); error(); return; } io_object.set_pollin(handle); // Speculative read. io_object.in_event(); }