privatestaticvoidprocessSelectedKey(SelectionKeyk,AbstractNioChannelch){finalNioUnsafeunsafe=ch.unsafe();if(!k.isValid()){// close the channel if the key is not valid anymoreunsafe.close(unsafe.voidPromise());return;}try{intreadyOps=k.readyOps();// Also check for readOps of 0 to workaround possible JDK bug which may otherwise lead// to a spin loopif((readyOps&(SelectionKey.OP_READ|SelectionKey.OP_ACCEPT))!=0||readyOps==0){unsafe.read();if(!ch.isOpen()){// Connection already closed - no need to handle write.return;}}if((readyOps&SelectionKey.OP_WRITE)!=0){// Call forceFlush which will also take care of clear the OP_WRITE once there is nothing left to writech.unsafe().forceFlush();}if((readyOps&SelectionKey.OP_CONNECT)!=0){// remove OP_CONNECT as otherwise Selector.select(..) will always return without blocking// See https://github.com/netty/netty/issues/924intops=k.interestOps();ops&=~SelectionKey.OP_CONNECT;k.interestOps(ops);unsafe.finishConnect();}}catch(CancelledKeyExceptionignored){unsafe.close(unsafe.voidPromise());}}
@Overridepublicvoidread(){asserteventLoop().inEventLoop();finalChannelConfigconfig=config();if(!config.isAutoRead()&&!isReadPending()){// ChannelConfig.setAutoRead(false) was called in the meantimeremoveReadOp();return;}finalintmaxMessagesPerRead=config.getMaxMessagesPerRead();finalChannelPipelinepipeline=pipeline();booleanclosed=false;Throwableexception=null;try{try{for(;;){intlocalRead=doReadMessages(readBuf);if(localRead==0){break;}if(localRead<0){closed=true;break;}// stop reading and remove opif(!config.isAutoRead()){break;}if(readBuf.size()>=maxMessagesPerRead){break;}}}catch(Throwablet){exception=t;}setReadPending(false);intsize=readBuf.size();for(inti=0;i<size;i++){pipeline.fireChannelRead(readBuf.get(i));}readBuf.clear();pipeline.fireChannelReadComplete();if(exception!=null){if(exceptioninstanceofIOException&&!(exceptioninstanceofPortUnreachableException)){// ServerChannel should not be closed even on IOException because it can often continue// accepting incoming connections. (e.g. too many open files)closed=!(AbstractNioMessageChannel.thisinstanceofServerChannel);}pipeline.fireExceptionCaught(exception);}if(closed){if(isOpen()){close(voidPromise());}}}finally{// Check if there is a readPending which was not processed yet.// This could be for two reasons:// * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...) method// * The user called Channel.read() or ChannelHandlerContext.read() in channelReadComplete(...) method//// See https://github.com/netty/netty/issues/2254if(!config.isAutoRead()&&!isReadPending()){removeReadOp();}}}