@Override public <V> Promise<V> newPromise() { return new DefaultPromise<V>(this); }
@Override public ChannelPromise setSuccess(Void result) { super.setSuccess(result); return this; }
@Override public ProgressivePromise<V> setFailure(Throwable cause) { super.setFailure(cause); return this; } }
@Override public Promise<V> syncUninterruptibly() { awaitUninterruptibly(); rethrowIfFailed(); return this; }
@Override public Promise<V> sync() throws InterruptedException { await(); rethrowIfFailed(); return this; }
final Promise<ScriptObjectMirror> pluginInitPromise = new DefaultPromise<>(jsEventLoop); unsafe.put(pluginInitPromiseKey, pluginInitPromise); jsEventLoop.submit(() -> { pluginLogger.info("Loading plugin: {} (revision: {})", path, revision.text());
/** * Create a promise that emits a {@code Boolean} value on completion of the {@code future} * * @param future the future. * @return Promise emitting a {@code Boolean} value. {@literal true} if the {@code future} completed successfully, otherwise * the cause wil be transported. */ static Promise<Boolean> toBooleanPromise(Future<?> future) { DefaultPromise<Boolean> result = new DefaultPromise<>(GlobalEventExecutor.INSTANCE); if (future.isDone() || future.isCancelled()) { if (future.isSuccess()) { result.setSuccess(true); } else { result.setFailure(future.cause()); } return result; } future.addListener((GenericFutureListener<Future<Object>>) f -> { if (f.isSuccess()) { result.setSuccess(true); } else { result.setFailure(f.cause()); } }); return result; }
@Override public Promise<Boolean> release(EventExecutorGroup eventLoopGroup, long quietPeriod, long timeout, TimeUnit unit) { logger.debug("Release executor {}", eventLoopGroup); Class<?> key = getKey(release(eventLoopGroup)); if ((key == null && eventLoopGroup.isShuttingDown()) || refCounter.containsKey(eventLoopGroup)) { DefaultPromise<Boolean> promise = new DefaultPromise<Boolean>(GlobalEventExecutor.INSTANCE); promise.setSuccess(true); return promise; } if (key != null) { eventLoopGroups.remove(key); } Future<?> shutdownFuture = eventLoopGroup.shutdownGracefully(quietPeriod, timeout, unit); return toBooleanPromise(shutdownFuture); }
@Override public Promise<V> await() throws InterruptedException { if (isDone()) { return this; } if (Thread.interrupted()) { throw new InterruptedException(toString()); } checkDeadLock(); synchronized (this) { while (!isDone()) { incWaiters(); try { wait(); } finally { decWaiters(); } } } return this; }
@Override public ChannelPromise await() throws InterruptedException { super.await(); return this; }
@Override public DefaultChannelGroupFuture addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners) { super.addListeners(listeners); return this; }
@Override public DefaultChannelGroupFuture addListener(GenericFutureListener<? extends Future<? super Void>> listener) { super.addListener(listener); return this; }
@Override public ProgressivePromise<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener) { super.removeListener(listener); return this; }
@Override public ChannelPromise awaitUninterruptibly() { super.awaitUninterruptibly(); return this; }
@Override protected void checkDeadLock() { if (ctx == null) { // If ctx is null the handlerAdded(...) callback was not called, in this case the checkDeadLock() // method was called from another Thread then the one that is used by ctx.executor(). We need to // guard against this as a user can see a race if handshakeFuture().sync() is called but the // handlerAdded(..) method was not yet as it is called from the EventExecutor of the // ChannelHandlerContext. If we not guard against this super.checkDeadLock() would cause an // IllegalStateException when trying to call executor(). return; } super.checkDeadLock(); } }
final Promise<ScriptObjectMirror> pluginInitPromise = new DefaultPromise<>(jsEventLoop); unsafe.put(pluginInitPromiseKey, pluginInitPromise); jsEventLoop.submit(() -> { pluginLogger.info("Loading plugin: {} (revision: {})", path, revision.text());
@Override @SuppressWarnings("unchecked") public Future<Boolean> shutdown(long quietPeriod, long timeout, TimeUnit timeUnit) { logger.debug("Initiate shutdown ({}, {}, {})", quietPeriod, timeout, timeUnit); shutdownCalled = true; Map<Class<? extends EventExecutorGroup>, EventExecutorGroup> copy = new HashMap<>(eventLoopGroups); DefaultPromise<Boolean> overall = new DefaultPromise<>(GlobalEventExecutor.INSTANCE); DefaultPromise<Boolean> lastRelease = new DefaultPromise<>(GlobalEventExecutor.INSTANCE); Futures.PromiseAggregator<Boolean, Promise<Boolean>> aggregator = new Futures.PromiseAggregator<>(overall); aggregator.expectMore(1 + copy.size()); aggregator.arm(); for (EventExecutorGroup executorGroup : copy.values()) { Promise<Boolean> shutdown = toBooleanPromise(release(executorGroup, quietPeriod, timeout, timeUnit)); aggregator.add(shutdown); } aggregator.add(lastRelease); lastRelease.setSuccess(null); return toBooleanPromise(overall); } }
@Override public Promise<V> awaitUninterruptibly() { if (isDone()) { return this; } checkDeadLock(); boolean interrupted = false; synchronized (this) { while (!isDone()) { incWaiters(); try { wait(); } catch (InterruptedException e) { // Interrupted while waiting. interrupted = true; } finally { decWaiters(); } } } if (interrupted) { Thread.currentThread().interrupt(); } return this; }
@Override public DefaultChannelGroupFuture await() throws InterruptedException { super.await(); return this; }
@Override public ChannelPromise addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners) { super.addListeners(listeners); return this; }