for (inti=0; i < nThreads; i ++) { booleansuccess=false; try { children[i] = newChild(threadFactory, args); success = true; } catch (Exception e) { // TODO: Think about if this is a good exception type thrownewIllegalStateException("failed to create a child event loop", e); } }
privatevoidprocessSelectedKeysPlain(Set<SelectionKey> selectedKeys) { // check if the set is empty and if so just return to not create garbage by // creating a new Iterator every time even if there is nothing to process. // See https://github.com/netty/netty/issues/597 if (selectedKeys.isEmpty()) { return; }
Iterator<SelectionKey> i = selectedKeys.iterator(); for (;;) { finalSelectionKeyk= i.next(); // 取出SelectionKey的附件 finalObjecta= k.attachment(); i.remove();
if (needsToSelectAgain) { selectAgain(); selectedKeys = selector.selectedKeys();
// Create the iterator again to avoid ConcurrentModificationException if (selectedKeys.isEmpty()) { break; } else { i = selectedKeys.iterator(); } } } }
try { intreadyOps= k.readyOps(); // Also check for readOps of 0 to workaround possible JDK bug which may otherwise lead // to a spin loop if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) { // 如果是读事件或者连接的事件,则直接调用read方法 unsafe.read(); if (!ch.isOpen()) { // Connection already closed - no need to handle write. return; } } if ((readyOps & SelectionKey.OP_WRITE) != 0) { // 如果是写操作位, 则说明有半包消息没有写完, 需要继续 ch.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/924 intops= k.interestOps(); ops &= ~SelectionKey.OP_CONNECT; k.interestOps(ops);