src/main/java/com/wizzardo/epoll/EpollCore.java
@Override
    public void run() {
        started = true;
        System.out.println("io threads count: " + ioThreadsCount);
        ioThreads = new IOThread[ioThreadsCount];
        for (int i = 0; i < ioThreadsCount; i++) {
            ioThreads[i] = createIOThread(i, ioThreadsCount);
            ioThreads[i].setTTL(ttl);
            ioThreads[i].loadCertificates(sslConfig);
            ioThreads[i].start();
        }

        ByteBuffer eventsBuffer = this.events;
        byte[] events = new byte[eventsBuffer.capacity()];
        byte[] newConnections = new byte[eventsBuffer.capacity()];

        if (ioThreadsCount == 0) {
            IOThread<? extends T> ioThread = createIOThread(1, 1);
            ioThreadsCount = 1;
            ioThread.scope = scope;
            ioThreads = new IOThread[]{ioThread};
            ioThreads[0].setTTL(ttl);
            ioThreads[0].loadCertificates(sslConfig);

            long prev = System.nanoTime();
            while (running) {
                try {
                    eventsBuffer.position(0);
                    long now = System.nanoTime() * 1000;
                    long nowMinusSecond = now - 1_000_000_000_000L; // 1 sec
                    int r = waitForEvents(500);
                    eventsBuffer.limit(r);
                    eventsBuffer.get(events, 0, r);
                    int i = 0;
                    while (i < r) {
                        int event = events[i];
                        if (event == 0) {
                            acceptConnections(newConnections);
                        } else {
                            int fd = readInt(events, i + 1);
                            ioThread.handleEvent(fd, event, now, nowMinusSecond);
                        }
                        i += 5;
                    }
                    if (nowMinusSecond > prev) {
                        ioThread.handleTimeOuts(now);
                        prev = now;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return;
        }

        while (running) {
            try {
                eventsBuffer.position(0);
                int r = waitForEvents(500);
                eventsBuffer.limit(r);
                eventsBuffer.get(events, 0, r);
                int i = 0;
                while (i < r) {
                    int event = events[i];
                    i += 5;
                    if (event == 0)
                        acceptConnections(newConnections);
                    else
                        throw new IllegalStateException("this thread only for accepting new connections, event: " + event);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        for (int i = 0; i < ioThreads.length; i++) {
            ioThreads[i].close();
        }
    }
@Override
    public void run() {
        started = true;
        System.out.println("io threads count: " + ioThreadsCount);
        ioThreads = new IOThread[ioThreadsCount];
        for (int i = 0; i < ioThreadsCount; i++) {
            ioThreads[i] = createIOThread(i, ioThreadsCount);
            ioThreads[i].setTTL(ttl);
            ioThreads[i].loadCertificates(sslConfig);
            ioThreads[i].start();
        }

        ByteBuffer eventsBuffer = this.events;
        byte[] events = new byte[eventsBuffer.capacity()];
        byte[] newConnections = new byte[eventsBuffer.capacity()];

        if (ioThreadsCount == 0) {
            IOThread<? extends T> ioThread = createIOThread(1, 1);
            ioThreadsCount = 1;
            ioThread.scope = scope;
            ioThreads = new IOThread[]{ioThread};
            ioThreads[0].setTTL(ttl);
            ioThreads[0].loadCertificates(sslConfig);

            long prev = System.nanoTime();
            while (running) {
                try {
                    eventsBuffer.position(0);
                    long now = System.nanoTime() * 1000;
                    long nowMinusSecond = now - 1_000_000_000_000L; // 1 sec
                    int r = waitForEvents(500);
                    eventsBuffer.limit(r);
                    eventsBuffer.get(events, 0, r);
                    int i = 0;
                    while (i < r) {
                        int event = events[i];
                        if (event == 0) {
                            acceptConnections(newConnections);
                        } else {
                            int fd = readInt(events, i + 1);
                            ioThread.handleEvent(fd, event, now, nowMinusSecond);
                        }
                        i += 5;
                    }
                    if (nowMinusSecond > prev) {
                        ioThread.handleTimeOuts(now);
                        prev = now;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return;
        }

        while (running) {
            try {
                eventsBuffer.position(0);
                int r = waitForEvents(500);
                eventsBuffer.limit(r);
                eventsBuffer.get(events, 0, r);
                int i = 0;
                while (i < r) {
                    int event = events[i];
                    i += 5;
                    if (event == 0)
                        acceptConnections(newConnections);
                    else
                        throw new IllegalStateException("this thread only for accepting new connections, event: " + event);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        for (int i = 0; i < ioThreads.length; i++) {
            ioThreads[i].close();
        }
    }
protected AtomicInteger eventCounter = new AtomicInteger(0);