Skip to content

other netty_epoll

ceragon edited this page Feb 1, 2022 · 3 revisions

Netty 的 EPoll

epoll_ctl 方法对比

jdk 的 epoll

jdk 的 native 接口如下:

class EPoll {
    static native int ctl(int epfd, int opcode, int fd, int events);
}
class EPollSelectorImpl extends SelectorImpl {
    private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();

    private void processUpdateQueue() {
        synchronized (updateLock) {
            SelectionKeyImpl ski;
            while ((ski = updateKeys.pollFirst()) != null) {
                int newEvents = ski.translateInterestOps();
                int registeredEvents = ski.registeredEvents();
                if (newEvents != registeredEvents) {
                    if (newEvents == 0) {
                        // remove from epoll
                        EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0);
                    } else {
                        if (registeredEvents == 0) {
                            // add to epoll
                            EPoll.ctl(epfd, EPOLL_CTL_ADD, fd, newEvents);
                        } else {
                            // modify events
                            EPoll.ctl(epfd, EPOLL_CTL_MOD, fd, newEvents);
                        }
                    }
                    ski.registeredEvents(newEvents);
                }
            }
        }
    }
}

调用路径

详情
class EPollSelectorImpl extends SelectorImpl {
    protected int doSelect(Consumer<SelectionKey> action, long timeout) throws IOException {
        // 处理需要修改监听事件的 fd 列表,并调用 epll.ctl() 方法
        processUpdateQueue();
        long startTime = timedPoll ? System.nanoTime() : 0;
        // 调用 epoll 的 epoll_wait 方法
        numEntries = EPoll.wait(epfd, pollArrayAddress, NUM_EPOLLEVENTS, to);
    }
}
abstract class SelectorImpl extends AbstractSelector {
    private int lockAndDoSelect(Consumer<SelectionKey> action, long timeout) throws IOException {
        return doSelect(action, timeout);
    }

    public final int select(long timeout) throws IOException {
        return lockAndDoSelect(null, (timeout == 0) ? -1 : timeout);
    }
}
public final class NioEventLoop extends SingleThreadEventLoop {
    private int select(long deadlineNanos) throws IOException {
        return timeoutMillis <= 0 ? selector.selectNow() : selector.select(timeoutMillis);
    }

    protected void run() {
        for (; ; ) {
            long curDeadlineNanos = nextScheduledTaskDeadlineNanos();
            strategy = select(curDeadlineNanos);
        }
    }
}

Clone this wiki locally