@Override protected void doFlushMessageBuffer(Queue<Object> buf) throws Exception { if (state < 2) { throw new NotYetConnectedException(); } if (state > 2) { throw new ClosedChannelException(); } final LocalChannel peer = this.peer; assert peer != null; Queue<Object> out = peer.pipeline().inboundMessageBuffer(); for (; ; ) { Object msg = buf.poll(); if (msg == null) { break; } out.add(msg); } peer.eventLoop() .execute( new Runnable() { @Override public void run() { peer.pipeline().fireInboundBufferUpdated(); } }); }
@Override protected void doWrite(ChannelOutboundBuffer in) throws Exception { switch (state) { case OPEN: case BOUND: throw new NotYetConnectedException(); case CLOSED: throw new ClosedChannelException(); } final LocalChannel peer = this.peer; final ChannelPipeline peerPipeline = peer.pipeline(); final EventLoop peerLoop = peer.eventLoop(); if (peerLoop == eventLoop()) { for (; ; ) { Object msg = in.current(); if (msg == null) { break; } peer.inboundBuffer.add(msg); ReferenceCountUtil.retain(msg); in.remove(); } finishPeerRead(peer, peerPipeline); } else { // Use a copy because the original msgs will be recycled by AbstractChannel. final Object[] msgsCopy = new Object[in.size()]; for (int i = 0; i < msgsCopy.length; i++) { msgsCopy[i] = ReferenceCountUtil.retain(in.current()); in.remove(); } peerLoop.execute( new Runnable() { @Override public void run() { Collections.addAll(peer.inboundBuffer, msgsCopy); finishPeerRead(peer, peerPipeline); } }); } }