@Override
    public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
        long deadline = System.nanoTime() + unit.toNanos(timeout);
        for (EventLoop l: activeChildren) {
            for (;;) {
                long timeLeft = deadline - System.nanoTime();
                if (timeLeft <= 0) {
                    return isTerminated();
                }
                if (l.awaitTermination(timeLeft, TimeUnit.NANOSECONDS)) {
                    break;
                }
            }
        }
        for (EventLoop l: idleChildren) {
            for (;;) {
                long timeLeft = deadline - System.nanoTime();
                if (timeLeft <= 0) {
                    return isTerminated();
                }
                if (l.awaitTermination(timeLeft, TimeUnit.NANOSECONDS)) {
                    break;
                }
            }
        }
        return isTerminated();
    }
@Test
    public void testTerminationFutureSuccessReflectively() throws Exception {
        Field terminationFutureField =
                ThreadPerChannelEventLoopGroup.class.getDeclaredField("terminationFuture");
        terminationFutureField.setAccessible(true);
        final Exception[] exceptionHolder = new Exception[1];
        for (int i = 0; i < 2; i++) {
            ThreadPerChannelEventLoopGroup loopGroup = new ThreadPerChannelEventLoopGroup(64);
            Promise<?> promise = new DefaultPromise<Void>(GlobalEventExecutor.INSTANCE) {
                @Override
                public Promise<Void> setSuccess(Void result) {
                    try {
                        return super.setSuccess(result);
                    } catch (IllegalStateException e) {
                        exceptionHolder[0] = e;
                        throw e;
                    }
                }
            };
            terminationFutureField.set(loopGroup, promise);
            runTest(loopGroup);
        }
        // The global event executor will not terminate, but this will give the test a chance to fail.
        GlobalEventExecutor.INSTANCE.awaitTermination(100, TimeUnit.MILLISECONDS);
        assertNull(exceptionHolder[0]);
    }