Repository: netty/netty
File: transport/src/main/java/io/netty/channel/nio/NioIoHandler.java (Java)

Code before:
            }
        } catch (CancelledKeyException e) {
            if (logger.isDebugEnabled()) {
                logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector {} - JDK bug?",
                        selector, e);
            }
            // Harmless exception - log anyway
        }
    }

    int selectNow() throws IOException {
        try {
            return selector.selectNow();
        } finally {
            // restore wakeup state if needed
            if (wakenUp.get()) {
                selector.wakeup();
            }
        }
    }

    private Selector selectRebuildSelector(int selectCnt) throws IOException {
        // The selector returned prematurely many times in a row.
        // Rebuild the selector to work around the problem.
        logger.warn(
                "Selector.select() returned prematurely {} times in a row; rebuilding Selector {}.",
                selectCnt, selector);

        rebuildSelector0();
        Selector selector = this.selector;

        // Select again to populate selectedKeys.
        selector.selectNow();
        return selector;
    }

    private void selectAgain() {
        needsToSelectAgain = false;
        try {
            selector.selectNow();
        } catch (Throwable t) {
            logger.warn("Failed to update SelectionKeys.", t);
        }
    }

    /**
     * Returns a new {@link IoHandlerFactory} that creates {@link NioIoHandler} instances
     *
     * @return factory                  the {@link IoHandlerFactory}.
     */
    public static IoHandlerFactory newFactory() {

Review comment (suggestion):
@normanmaurer this is the actual fix: i was observing a select without any timeout to still call selectNow instead - which is not right

Code after:
                    break;
                }

                currentTimeNanos = time;
            }

            if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Selector.select() returned prematurely {} times in a row for Selector {}.",
                            selectCnt - 1, selector);
                }
            }
        } catch (CancelledKeyException e) {
            if (logger.isDebugEnabled()) {
                logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector {} - JDK bug?",
                        selector, e);
            }
            // Harmless exception - log anyway
        }
    }

    private static long millisBeforeDeadline(long selectDeadLineNanos, long currentTimeNanos) {
        assert selectDeadLineNanos != Long.MAX_VALUE;
        long nanosBeforeDeadline = selectDeadLineNanos - currentTimeNanos;
        // Prevent overflow when adding the rounding bias:
        // if we don't do this, it would appear as the deadline is already reached!
        if (nanosBeforeDeadline >= Long.MAX_VALUE - 500_000L) {
            return Long.MAX_VALUE / 1_000_000L;
        }
        // Add 500_000 to round up to the nearest millisecond.
        return (nanosBeforeDeadline + 500_000L) / 1_000_000L;
    }

    int selectNow() throws IOException {
        try {
            return selector.selectNow();
        } finally {
            // restore wakeup state if needed
            if (wakenUp.get()) {
                selector.wakeup();
            }
        }
    }

    private Selector selectRebuildSelector(int selectCnt) throws IOException {
        // The selector returned prematurely many times in a row.
        // Rebuild the selector to work around the problem.
        logger.warn(
                "Selector.select() returned prematurely {} times in a row; rebuilding Selector {}.",
                selectCnt, selector);