Java 8 migration: replace anonymous types with lambda (#8751)

Motivation:

We can use lambdas instead of anonymous inner class to improve readablity

Modification:

Replace anonymous inner class with lambda

Result:

Cleaner code that uses Java8 features
This commit is contained in:
kezhenxu94 2019-01-25 17:51:05 +08:00 committed by Norman Maurer
parent 7b6336f1fd
commit d08ecccd9a
36 changed files with 585 additions and 1265 deletions

View File

@ -244,17 +244,14 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C, F>, C
} else { } else {
// Registration future is almost always fulfilled already, but just in case it's not. // Registration future is almost always fulfilled already, but just in case it's not.
final ChannelPromise promise = channel.newPromise(); final ChannelPromise promise = channel.newPromise();
regFuture.addListener(new ChannelFutureListener() { regFuture.addListener((ChannelFutureListener) future -> {
@Override Throwable cause = future.cause();
public void operationComplete(ChannelFuture future) throws Exception { if (cause != null) {
Throwable cause = future.cause(); // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an
if (cause != null) { // IllegalStateException once we try to access the EventLoop of the Channel.
// Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an promise.setFailure(cause);
// IllegalStateException once we try to access the EventLoop of the Channel. } else {
promise.setFailure(cause); doBind0(regFuture, channel, localAddress, promise);
} else {
doBind0(regFuture, channel, localAddress, promise);
}
} }
}); });
return promise; return promise;
@ -271,22 +268,14 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C, F>, C
} }
final ChannelPromise promise = channel.newPromise(); final ChannelPromise promise = channel.newPromise();
loop.execute(new Runnable() { loop.execute(() -> init(channel).addListener((ChannelFutureListener) future -> {
@Override if (future.isSuccess()) {
public void run() { channel.register(promise);
init(channel).addListener(new ChannelFutureListener() { } else {
@Override channel.unsafe().closeForcibly();
public void operationComplete(ChannelFuture future) throws Exception { promise.setFailure(future.cause());
if (future.isSuccess()) {
channel.register(promise);
} else {
channel.unsafe().closeForcibly();
promise.setFailure(future.cause());
}
}
});
} }
}); }));
return promise; return promise;
} }
@ -301,14 +290,11 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C, F>, C
// This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up // This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up
// the pipeline in its channelRegistered() implementation. // the pipeline in its channelRegistered() implementation.
channel.eventLoop().execute(new Runnable() { channel.eventLoop().execute(() -> {
@Override if (regFuture.isSuccess()) {
public void run() { channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
if (regFuture.isSuccess()) { } else {
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE); promise.setFailure(regFuture.cause());
} else {
promise.setFailure(regFuture.cause());
}
} }
}); });
} }

View File

@ -206,19 +206,16 @@ public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel, ChannelFact
} else { } else {
// Registration future is almost always fulfilled already, but just in case it's not. // Registration future is almost always fulfilled already, but just in case it's not.
final ChannelPromise promise = channel.newPromise(); final ChannelPromise promise = channel.newPromise();
regFuture.addListener(new ChannelFutureListener() { regFuture.addListener((ChannelFutureListener) future -> {
@Override // Directly obtain the cause and do a null check so we only need one volatile read in case of a
public void operationComplete(ChannelFuture future) throws Exception { // failure.
// Directly obtain the cause and do a null check so we only need one volatile read in case of a Throwable cause = future.cause();
// failure. if (cause != null) {
Throwable cause = future.cause(); // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an
if (cause != null) { // IllegalStateException once we try to access the EventLoop of the Channel.
// Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an promise.setFailure(cause);
// IllegalStateException once we try to access the EventLoop of the Channel. } else {
promise.setFailure(cause); doResolveAndConnect0(channel, remoteAddress, localAddress, promise);
} else {
doResolveAndConnect0(channel, remoteAddress, localAddress, promise);
}
} }
}); });
return promise; return promise;
@ -254,15 +251,12 @@ public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel, ChannelFact
} }
// Wait until the name resolution is finished. // Wait until the name resolution is finished.
resolveFuture.addListener(new FutureListener<SocketAddress>() { resolveFuture.addListener((FutureListener<SocketAddress>) future -> {
@Override if (future.cause() != null) {
public void operationComplete(Future<SocketAddress> future) throws Exception { channel.close();
if (future.cause() != null) { promise.setFailure(future.cause());
channel.close(); } else {
promise.setFailure(future.cause()); doConnect(future.getNow(), localAddress, promise);
} else {
doConnect(future.getNow(), localAddress, promise);
}
} }
}); });
} catch (Throwable cause) { } catch (Throwable cause) {
@ -277,16 +271,13 @@ public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel, ChannelFact
// This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up // This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up
// the pipeline in its channelRegistered() implementation. // the pipeline in its channelRegistered() implementation.
final Channel channel = connectPromise.channel(); final Channel channel = connectPromise.channel();
channel.eventLoop().execute(new Runnable() { channel.eventLoop().execute(() -> {
@Override if (localAddress == null) {
public void run() { channel.connect(remoteAddress, connectPromise);
if (localAddress == null) { } else {
channel.connect(remoteAddress, connectPromise); channel.connect(remoteAddress, localAddress, connectPromise);
} else {
channel.connect(remoteAddress, localAddress, connectPromise);
}
connectPromise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} }
connectPromise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}); });
} }

View File

@ -214,13 +214,10 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
pipeline.addLast(handler); pipeline.addLast(handler);
} }
ch.eventLoop().execute(new Runnable() { ch.eventLoop().execute(() -> {
@Override pipeline.addLast(new ServerBootstrapAcceptor(
public void run() { ch, currentChildHandler, currentChildOptions, currentChildAttrs));
pipeline.addLast(new ServerBootstrapAcceptor( promise.setSuccess();
ch, currentChildHandler, currentChildOptions, currentChildAttrs));
promise.setSuccess();
}
}); });
} }
}); });
@ -277,12 +274,7 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
// not be able to load the class because of the file limit it already reached. // not be able to load the class because of the file limit it already reached.
// //
// See https://github.com/netty/netty/issues/1328 // See https://github.com/netty/netty/issues/1328
enableAutoReadTask = new Runnable() { enableAutoReadTask = () -> channel.config().setAutoRead(true);
@Override
public void run() {
channel.config().setAutoRead(true);
}
};
} }
@Override @Override
@ -295,12 +287,7 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
initChild(child); initChild(child);
} else { } else {
try { try {
childEventLoop.execute(new Runnable() { childEventLoop.execute(() -> initChild(child));
@Override
public void run() {
initChild(child);
}
});
} catch (Throwable cause) { } catch (Throwable cause) {
forceClose(child, cause); forceClose(child, cause);
} }
@ -319,12 +306,9 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue()); child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
} }
child.register().addListener(new ChannelFutureListener() { child.register().addListener((ChannelFutureListener) future -> {
@Override if (!future.isSuccess()) {
public void operationComplete(ChannelFuture future) throws Exception { forceClose(child, future.cause());
if (!future.isSuccess()) {
forceClose(child, future.cause());
}
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {

View File

@ -550,12 +550,9 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
} }
if (!wasActive && isActive()) { if (!wasActive && isActive()) {
invokeLater(new Runnable() { invokeLater(() -> {
@Override pipeline.fireChannelActive();
public void run() { readIfIsAutoRead();
pipeline.fireChannelActive();
readIfIsAutoRead();
}
}); });
} }
@ -580,12 +577,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
} }
if (wasActive && !isActive()) { if (wasActive && !isActive()) {
invokeLater(new Runnable() { invokeLater(pipeline::fireChannelInactive);
@Override
public void run() {
pipeline.fireChannelInactive();
}
});
} }
safeSetSuccess(promise); safeSetSuccess(promise);
@ -631,24 +623,17 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
new ChannelOutputShutdownException("Channel output shutdown", cause); new ChannelOutputShutdownException("Channel output shutdown", cause);
Executor closeExecutor = prepareToClose(); Executor closeExecutor = prepareToClose();
if (closeExecutor != null) { if (closeExecutor != null) {
closeExecutor.execute(new Runnable() { closeExecutor.execute(() -> {
@Override try {
public void run() { // Execute the shutdown.
try { doShutdownOutput();
// Execute the shutdown. promise.setSuccess();
doShutdownOutput(); } catch (Throwable err) {
promise.setSuccess(); promise.setFailure(err);
} catch (Throwable err) { } finally {
promise.setFailure(err); // Dispatch to the EventLoop
} finally { eventLoop().execute(() ->
// Dispatch to the EventLoop closeOutboundBufferForShutdown(pipeline, outboundBuffer, shutdownCause));
eventLoop().execute(new Runnable() {
@Override
public void run() {
closeOutboundBufferForShutdown(pipeline, outboundBuffer, shutdownCause);
}
});
}
} }
}); });
} else { } else {
@ -683,12 +668,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
safeSetSuccess(promise); safeSetSuccess(promise);
} else if (!(promise instanceof VoidChannelPromise)) { // Only needed if no VoidChannelPromise. } else if (!(promise instanceof VoidChannelPromise)) { // Only needed if no VoidChannelPromise.
// This means close() was called before so we just register a listener and return // This means close() was called before so we just register a listener and return
closeFuture.addListener(new ChannelFutureListener() { closeFuture.addListener((ChannelFutureListener) future -> promise.setSuccess());
@Override
public void operationComplete(ChannelFuture future) throws Exception {
promise.setSuccess();
}
});
} }
return; return;
} }
@ -700,26 +680,20 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
this.outboundBuffer = null; // Disallow adding any messages and flushes to outboundBuffer. this.outboundBuffer = null; // Disallow adding any messages and flushes to outboundBuffer.
Executor closeExecutor = prepareToClose(); Executor closeExecutor = prepareToClose();
if (closeExecutor != null) { if (closeExecutor != null) {
closeExecutor.execute(new Runnable() { closeExecutor.execute(() -> {
@Override try {
public void run() { // Execute the close.
try { doClose0(promise);
// Execute the close. } finally {
doClose0(promise); // Call invokeLater so closeAndDeregister is executed in the EventLoop again!
} finally { invokeLater(() -> {
// Call invokeLater so closeAndDeregister is executed in the EventLoop again! if (outboundBuffer != null) {
invokeLater(new Runnable() { // Fail all the queued messages
@Override outboundBuffer.failFlushed(cause, notify);
public void run() { outboundBuffer.close(closeCause);
if (outboundBuffer != null) { }
// Fail all the queued messages fireChannelInactiveAndDeregister(wasActive);
outboundBuffer.failFlushed(cause, notify); });
outboundBuffer.close(closeCause);
}
fireChannelInactiveAndDeregister(wasActive);
}
});
}
} }
}); });
} else { } else {
@ -734,12 +708,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
} }
} }
if (inFlush0) { if (inFlush0) {
invokeLater(new Runnable() { invokeLater(() -> fireChannelInactiveAndDeregister(wasActive));
@Override
public void run() {
fireChannelInactiveAndDeregister(wasActive);
}
});
} else { } else {
fireChannelInactiveAndDeregister(wasActive); fireChannelInactiveAndDeregister(wasActive);
} }
@ -796,27 +765,24 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
// //
// See: // See:
// https://github.com/netty/netty/issues/4435 // https://github.com/netty/netty/issues/4435
invokeLater(new Runnable() { invokeLater(() -> {
@Override try {
public void run() { doDeregister();
try { } catch (Throwable t) {
doDeregister(); logger.warn("Unexpected exception occurred while deregistering a channel.", t);
} catch (Throwable t) { } finally {
logger.warn("Unexpected exception occurred while deregistering a channel.", t); if (fireChannelInactive) {
} finally { pipeline.fireChannelInactive();
if (fireChannelInactive) {
pipeline.fireChannelInactive();
}
// Some transports like local and AIO does not allow the deregistration of
// an open channel. Their doDeregister() calls close(). Consequently,
// close() calls deregister() again - no need to fire channelUnregistered, so check
// if it was registered.
if (registered) {
registered = false;
pipeline.fireChannelUnregistered();
}
safeSetSuccess(promise);
} }
// Some transports like local and AIO does not allow the deregistration of
// an open channel. Their doDeregister() calls close(). Consequently,
// close() calls deregister() again - no need to fire channelUnregistered, so check
// if it was registered.
if (registered) {
registered = false;
pipeline.fireChannelUnregistered();
}
safeSetSuccess(promise);
} }
}); });
} }
@ -832,12 +798,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
try { try {
doBeginRead(); doBeginRead();
} catch (final Exception e) { } catch (final Exception e) {
invokeLater(new Runnable() { invokeLater(() -> pipeline.fireExceptionCaught(e));
@Override
public void run() {
pipeline.fireExceptionCaught(e);
}
});
close(voidPromise()); close(voidPromise());
} }
} }

View File

@ -232,12 +232,8 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
private static boolean isSkippable( private static boolean isSkippable(
final Class<?> handlerType, final String methodName, final Class<?>... paramTypes) throws Exception { final Class<?> handlerType, final String methodName, final Class<?>... paramTypes) throws Exception {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() { return AccessController.doPrivileged((PrivilegedExceptionAction<Boolean>) () ->
@Override handlerType.getMethod(methodName, paramTypes).isAnnotationPresent(ChannelHandler.Skip.class));
public Boolean run() throws Exception {
return handlerType.getMethod(methodName, paramTypes).isAnnotationPresent(ChannelHandler.Skip.class);
}
});
} }
@Override @Override
@ -280,12 +276,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeChannelRegistered(); next.invokeChannelRegistered();
} else { } else {
executor.execute(new Runnable() { executor.execute(next::invokeChannelRegistered);
@Override
public void run() {
next.invokeChannelRegistered();
}
});
} }
} }
@ -312,12 +303,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeChannelUnregistered(); next.invokeChannelUnregistered();
} else { } else {
executor.execute(new Runnable() { executor.execute(next::invokeChannelUnregistered);
@Override
public void run() {
next.invokeChannelUnregistered();
}
});
} }
} }
@ -344,12 +330,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeChannelActive(); next.invokeChannelActive();
} else { } else {
executor.execute(new Runnable() { executor.execute(next::invokeChannelActive);
@Override
public void run() {
next.invokeChannelActive();
}
});
} }
} }
@ -376,12 +357,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeChannelInactive(); next.invokeChannelInactive();
} else { } else {
executor.execute(new Runnable() { executor.execute(next::invokeChannelInactive);
@Override
public void run() {
next.invokeChannelInactive();
}
});
} }
} }
@ -410,12 +386,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
next.invokeExceptionCaught(cause); next.invokeExceptionCaught(cause);
} else { } else {
try { try {
executor.execute(new Runnable() { executor.execute(() -> next.invokeExceptionCaught(cause));
@Override
public void run() {
next.invokeExceptionCaught(cause);
}
});
} catch (Throwable t) { } catch (Throwable t) {
if (logger.isWarnEnabled()) { if (logger.isWarnEnabled()) {
logger.warn("Failed to submit an exceptionCaught() event.", t); logger.warn("Failed to submit an exceptionCaught() event.", t);
@ -460,12 +431,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeUserEventTriggered(event); next.invokeUserEventTriggered(event);
} else { } else {
executor.execute(new Runnable() { executor.execute(() -> next.invokeUserEventTriggered(event));
@Override
public void run() {
next.invokeUserEventTriggered(event);
}
});
} }
} }
@ -493,12 +459,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeChannelRead(m); next.invokeChannelRead(m);
} else { } else {
executor.execute(new Runnable() { executor.execute(() -> next.invokeChannelRead(m));
@Override
public void run() {
next.invokeChannelRead(m);
}
});
} }
} }
@ -527,12 +488,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
} else { } else {
Runnable task = next.invokeChannelReadCompleteTask; Runnable task = next.invokeChannelReadCompleteTask;
if (task == null) { if (task == null) {
next.invokeChannelReadCompleteTask = task = new Runnable() { next.invokeChannelReadCompleteTask = task = next::invokeChannelReadComplete;
@Override
public void run() {
next.invokeChannelReadComplete();
}
};
} }
executor.execute(task); executor.execute(task);
} }
@ -563,12 +519,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
} else { } else {
Runnable task = next.invokeChannelWritableStateChangedTask; Runnable task = next.invokeChannelWritableStateChangedTask;
if (task == null) { if (task == null) {
next.invokeChannelWritableStateChangedTask = task = new Runnable() { next.invokeChannelWritableStateChangedTask = task = next::invokeChannelWritabilityChanged;
@Override
public void run() {
next.invokeChannelWritabilityChanged();
}
};
} }
executor.execute(task); executor.execute(task);
} }
@ -636,12 +587,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeBind(localAddress, promise); next.invokeBind(localAddress, promise);
} else { } else {
safeExecute(executor, new Runnable() { safeExecute(executor, () -> next.invokeBind(localAddress, promise), promise, null);
@Override
public void run() {
next.invokeBind(localAddress, promise);
}
}, promise, null);
} }
return promise; return promise;
} }
@ -680,12 +626,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeConnect(remoteAddress, localAddress, promise); next.invokeConnect(remoteAddress, localAddress, promise);
} else { } else {
safeExecute(executor, new Runnable() { safeExecute(executor, () -> next.invokeConnect(remoteAddress, localAddress, promise), promise, null);
@Override
public void run() {
next.invokeConnect(remoteAddress, localAddress, promise);
}
}, promise, null);
} }
return promise; return promise;
} }
@ -720,14 +661,11 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
next.invokeDisconnect(promise); next.invokeDisconnect(promise);
} }
} else { } else {
safeExecute(executor, new Runnable() { safeExecute(executor, () -> {
@Override if (!channel().metadata().hasDisconnect()) {
public void run() { next.invokeClose(promise);
if (!channel().metadata().hasDisconnect()) { } else {
next.invokeClose(promise); next.invokeDisconnect(promise);
} else {
next.invokeDisconnect(promise);
}
} }
}, promise, null); }, promise, null);
} }
@ -758,12 +696,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeClose(promise); next.invokeClose(promise);
} else { } else {
safeExecute(executor, new Runnable() { safeExecute(executor, () -> next.invokeClose(promise), promise, null);
@Override
public void run() {
next.invokeClose(promise);
}
}, promise, null);
} }
return promise; return promise;
@ -793,12 +726,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeRegister(promise); next.invokeRegister(promise);
} else { } else {
safeExecute(executor, new Runnable() { safeExecute(executor, () -> next.invokeRegister(promise), promise, null);
@Override
public void run() {
next.invokeRegister(promise);
}
}, promise, null);
} }
return promise; return promise;
@ -828,12 +756,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
next.invokeDeregister(promise); next.invokeDeregister(promise);
} else { } else {
safeExecute(executor, new Runnable() { safeExecute(executor, () -> next.invokeDeregister(promise), promise, null);
@Override
public void run() {
next.invokeDeregister(promise);
}
}, promise, null);
} }
return promise; return promise;
@ -860,12 +783,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
} else { } else {
Runnable task = next.invokeReadTask; Runnable task = next.invokeReadTask;
if (task == null) { if (task == null) {
next.invokeReadTask = task = new Runnable() { next.invokeReadTask = task = next::invokeRead;
@Override
public void run() {
next.invokeRead();
}
};
} }
executor.execute(task); executor.execute(task);
} }
@ -922,12 +840,7 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap
} else { } else {
Runnable task = next.invokeFlushTask; Runnable task = next.invokeFlushTask;
if (task == null) { if (task == null) {
next.invokeFlushTask = task = new Runnable() { next.invokeFlushTask = task = next::invokeFlush;
@Override
public void run() {
next.invokeFlush();
}
};
} }
safeExecute(executor, task, channel().voidPromise(), null); safeExecute(executor, task, channel().voidPromise(), null);
} }

View File

@ -38,23 +38,15 @@ public interface ChannelFutureListener extends GenericFutureListener<ChannelFutu
* A {@link ChannelFutureListener} that closes the {@link Channel} which is * A {@link ChannelFutureListener} that closes the {@link Channel} which is
* associated with the specified {@link ChannelFuture}. * associated with the specified {@link ChannelFuture}.
*/ */
ChannelFutureListener CLOSE = new ChannelFutureListener() { ChannelFutureListener CLOSE = future -> future.channel().close();
@Override
public void operationComplete(ChannelFuture future) {
future.channel().close();
}
};
/** /**
* A {@link ChannelFutureListener} that closes the {@link Channel} when the * A {@link ChannelFutureListener} that closes the {@link Channel} when the
* operation ended up with a failure or cancellation rather than a success. * operation ended up with a failure or cancellation rather than a success.
*/ */
ChannelFutureListener CLOSE_ON_FAILURE = new ChannelFutureListener() { ChannelFutureListener CLOSE_ON_FAILURE = future -> {
@Override if (!future.isSuccess()) {
public void operationComplete(ChannelFuture future) { future.channel().close();
if (!future.isSuccess()) {
future.channel().close();
}
} }
}; };
@ -62,12 +54,9 @@ public interface ChannelFutureListener extends GenericFutureListener<ChannelFutu
* A {@link ChannelFutureListener} that forwards the {@link Throwable} of the {@link ChannelFuture} into the * A {@link ChannelFutureListener} that forwards the {@link Throwable} of the {@link ChannelFuture} into the
* {@link ChannelPipeline}. This mimics the old behavior of Netty 3. * {@link ChannelPipeline}. This mimics the old behavior of Netty 3.
*/ */
ChannelFutureListener FIRE_EXCEPTION_ON_FAILURE = new ChannelFutureListener() { ChannelFutureListener FIRE_EXCEPTION_ON_FAILURE = future -> {
@Override if (!future.isSuccess()) {
public void operationComplete(ChannelFuture future) { future.channel().pipeline().fireExceptionCaught(future.cause());
if (!future.isSuccess()) {
future.channel().pipeline().fireExceptionCaught(future.cause());
}
} }
}; };

View File

@ -602,12 +602,7 @@ public final class ChannelOutboundBuffer {
if (invokeLater) { if (invokeLater) {
Runnable task = fireChannelWritabilityChangedTask; Runnable task = fireChannelWritabilityChangedTask;
if (task == null) { if (task == null) {
fireChannelWritabilityChangedTask = task = new Runnable() { fireChannelWritabilityChangedTask = task = pipeline::fireChannelWritabilityChanged;
@Override
public void run() {
pipeline.fireChannelWritabilityChanged();
}
};
} }
channel.eventLoop().execute(task); channel.eventLoop().execute(task);
} else { } else {
@ -654,12 +649,7 @@ public final class ChannelOutboundBuffer {
void close(final Throwable cause, final boolean allowChannelOpen) { void close(final Throwable cause, final boolean allowChannelOpen) {
if (inFail) { if (inFail) {
channel.eventLoop().execute(new Runnable() { channel.eventLoop().execute(() -> close(cause, allowChannelOpen));
@Override
public void run() {
close(cause, allowChannelOpen);
}
});
return; return;
} }

View File

@ -614,12 +614,7 @@ public class CombinedChannelDuplexHandler<I extends ChannelInboundHandler, O ext
if (executor.inEventLoop()) { if (executor.inEventLoop()) {
remove0(); remove0();
} else { } else {
executor.execute(new Runnable() { executor.execute(this::remove0);
@Override
public void run() {
remove0();
}
});
} }
} }

View File

@ -123,12 +123,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
EventExecutor ctxExecutor = newCtx.executor(); EventExecutor ctxExecutor = newCtx.executor();
if (!ctxExecutor.inEventLoop()) { if (!ctxExecutor.inEventLoop()) {
newCtx.setAddPending(); newCtx.setAddPending();
ctxExecutor.execute(new Runnable() { ctxExecutor.execute(() -> callHandlerAdded0(newCtx));
@Override
public void run() {
callHandlerAdded0(newCtx);
}
});
return this; return this;
} }
} }
@ -162,12 +157,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
EventExecutor ctxExecutor = newCtx.executor(); EventExecutor ctxExecutor = newCtx.executor();
if (!ctxExecutor.inEventLoop()) { if (!ctxExecutor.inEventLoop()) {
newCtx.setAddPending(); newCtx.setAddPending();
ctxExecutor.execute(new Runnable() { ctxExecutor.execute(() -> callHandlerAdded0(newCtx));
@Override
public void run() {
callHandlerAdded0(newCtx);
}
});
return this; return this;
} }
} }
@ -205,12 +195,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
EventExecutor ctxExecutor = newCtx.executor(); EventExecutor ctxExecutor = newCtx.executor();
if (!ctxExecutor.inEventLoop()) { if (!ctxExecutor.inEventLoop()) {
newCtx.setAddPending(); newCtx.setAddPending();
ctxExecutor.execute(new Runnable() { ctxExecutor.execute(() -> callHandlerAdded0(newCtx));
@Override
public void run() {
callHandlerAdded0(newCtx);
}
});
return this; return this;
} }
} }
@ -256,12 +241,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
EventExecutor ctxExecutor = newCtx.executor(); EventExecutor ctxExecutor = newCtx.executor();
if (!ctxExecutor.inEventLoop()) { if (!ctxExecutor.inEventLoop()) {
newCtx.setAddPending(); newCtx.setAddPending();
ctxExecutor.execute(new Runnable() { ctxExecutor.execute(() -> callHandlerAdded0(newCtx));
@Override
public void run() {
callHandlerAdded0(newCtx);
}
});
return this; return this;
} }
} }
@ -407,12 +387,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
EventExecutor executor = ctx.executor(); EventExecutor executor = ctx.executor();
if (!executor.inEventLoop()) { if (!executor.inEventLoop()) {
executor.execute(new Runnable() { executor.execute(() -> callHandlerRemoved0(ctx));
@Override
public void run() {
callHandlerRemoved0(ctx);
}
});
return ctx; return ctx;
} }
} }
@ -483,15 +458,12 @@ public class DefaultChannelPipeline implements ChannelPipeline {
EventExecutor executor = ctx.executor(); EventExecutor executor = ctx.executor();
if (!executor.inEventLoop()) { if (!executor.inEventLoop()) {
executor.execute(new Runnable() { executor.execute(() -> {
@Override // Invoke newHandler.handlerAdded() first (i.e. before oldHandler.handlerRemoved() is invoked)
public void run() { // because callHandlerRemoved() will trigger channelRead() or flush() on newHandler and
// Invoke newHandler.handlerAdded() first (i.e. before oldHandler.handlerRemoved() is invoked) // those event handlers must be called after handlerAdded().
// because callHandlerRemoved() will trigger channelRead() or flush() on newHandler and callHandlerAdded0(newCtx);
// those event handlers must be called after handlerAdded(). callHandlerRemoved0(ctx);
callHandlerAdded0(newCtx);
callHandlerRemoved0(ctx);
}
}); });
return ctx.handler(); return ctx.handler();
} }
@ -776,12 +748,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
final EventExecutor executor = ctx.executor(); final EventExecutor executor = ctx.executor();
if (!inEventLoop && !executor.inEventLoop(currentThread)) { if (!inEventLoop && !executor.inEventLoop(currentThread)) {
final AbstractChannelHandlerContext finalCtx = ctx; final AbstractChannelHandlerContext finalCtx = ctx;
executor.execute(new Runnable() { executor.execute(() -> destroyUp(finalCtx, true));
@Override
public void run() {
destroyUp(finalCtx, true);
}
});
break; break;
} }
@ -806,12 +773,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
callHandlerRemoved0(ctx); callHandlerRemoved0(ctx);
} else { } else {
final AbstractChannelHandlerContext finalCtx = ctx; final AbstractChannelHandlerContext finalCtx = ctx;
executor.execute(new Runnable() { executor.execute(() -> destroyDown(Thread.currentThread(), finalCtx, true));
@Override
public void run() {
destroyDown(Thread.currentThread(), finalCtx, true);
}
});
break; break;
} }

View File

@ -40,13 +40,10 @@ public final class VoidChannelPromise extends AbstractFuture<Void> implements Ch
} }
this.channel = channel; this.channel = channel;
if (fireException) { if (fireException) {
fireExceptionListener = new ChannelFutureListener() { fireExceptionListener = future -> {
@Override Throwable cause = future.cause();
public void operationComplete(ChannelFuture future) throws Exception { if (cause != null) {
Throwable cause = future.cause(); fireException0(cause);
if (cause != null) {
fireException0(cause);
}
} }
}; };
} else { } else {

View File

@ -59,12 +59,7 @@ public class EmbeddedChannel extends AbstractChannel {
private static final ChannelMetadata METADATA_NO_DISCONNECT = new ChannelMetadata(false); private static final ChannelMetadata METADATA_NO_DISCONNECT = new ChannelMetadata(false);
private static final ChannelMetadata METADATA_DISCONNECT = new ChannelMetadata(true); private static final ChannelMetadata METADATA_DISCONNECT = new ChannelMetadata(true);
private final ChannelFutureListener recordExceptionListener = new ChannelFutureListener() { private final ChannelFutureListener recordExceptionListener = this::recordException;
@Override
public void operationComplete(ChannelFuture future) throws Exception {
recordException(future);
}
};
private final ChannelMetadata metadata; private final ChannelMetadata metadata;
private final ChannelConfig config; private final ChannelConfig config;

View File

@ -23,12 +23,7 @@ import io.netty.channel.ServerChannel;
*/ */
public final class ChannelMatchers { public final class ChannelMatchers {
private static final ChannelMatcher ALL_MATCHER = new ChannelMatcher() { private static final ChannelMatcher ALL_MATCHER = channel -> true;
@Override
public boolean matches(Channel channel) {
return true;
}
};
private static final ChannelMatcher SERVER_CHANNEL_MATCHER = isInstanceOf(ServerChannel.class); private static final ChannelMatcher SERVER_CHANNEL_MATCHER = isInstanceOf(ServerChannel.class);
private static final ChannelMatcher NON_SERVER_CHANNEL_MATCHER = isNotInstanceOf(ServerChannel.class); private static final ChannelMatcher NON_SERVER_CHANNEL_MATCHER = isNotInstanceOf(ServerChannel.class);

View File

@ -46,12 +46,7 @@ public class DefaultChannelGroup extends AbstractSet<Channel> implements Channel
private final EventExecutor executor; private final EventExecutor executor;
private final ConcurrentMap<ChannelId, Channel> serverChannels = new ConcurrentHashMap<>(); private final ConcurrentMap<ChannelId, Channel> serverChannels = new ConcurrentHashMap<>();
private final ConcurrentMap<ChannelId, Channel> nonServerChannels = new ConcurrentHashMap<>(); private final ConcurrentMap<ChannelId, Channel> nonServerChannels = new ConcurrentHashMap<>();
private final ChannelFutureListener remover = new ChannelFutureListener() { private final ChannelFutureListener remover = future -> remove(future.channel());
@Override
public void operationComplete(ChannelFuture future) throws Exception {
remove(future.channel());
}
};
private final VoidChannelGroupFuture voidFuture = new VoidChannelGroupFuture(this); private final VoidChannelGroupFuture voidFuture = new VoidChannelGroupFuture(this);
private final boolean stayClosed; private final boolean stayClosed;
private volatile boolean closed; private volatile boolean closed;

View File

@ -63,13 +63,10 @@ public class LocalChannel extends AbstractChannel {
private final ChannelConfig config = new DefaultChannelConfig(this); private final ChannelConfig config = new DefaultChannelConfig(this);
// To further optimize this we could write our own SPSC queue. // To further optimize this we could write our own SPSC queue.
final Queue<Object> inboundBuffer = PlatformDependent.newSpscQueue(); final Queue<Object> inboundBuffer = PlatformDependent.newSpscQueue();
private final Runnable readTask = new Runnable() { private final Runnable readTask = () -> {
@Override // Ensure the inboundBuffer is not empty as readInbound() will always call fireChannelReadComplete()
public void run() { if (!inboundBuffer.isEmpty()) {
// Ensure the inboundBuffer is not empty as readInbound() will always call fireChannelReadComplete() readInbound();
if (!inboundBuffer.isEmpty()) {
readInbound();
}
} }
}; };
@ -197,12 +194,7 @@ public class LocalChannel extends AbstractChannel {
EventLoop peerEventLoop = peer.eventLoop(); EventLoop peerEventLoop = peer.eventLoop();
final boolean peerIsActive = peer.isActive(); final boolean peerIsActive = peer.isActive();
try { try {
peerEventLoop.execute(new Runnable() { peerEventLoop.execute(() -> peer.tryClose(peerIsActive));
@Override
public void run() {
peer.tryClose(peerIsActive);
}
});
} catch (Throwable cause) { } catch (Throwable cause) {
logger.warn("Releasing Inbound Queues for channels {}-{} because exception occurred!", logger.warn("Releasing Inbound Queues for channels {}-{} because exception occurred!",
this, peer, cause); this, peer, cause);
@ -350,12 +342,7 @@ public class LocalChannel extends AbstractChannel {
private void runFinishPeerReadTask(final LocalChannel peer) { private void runFinishPeerReadTask(final LocalChannel peer) {
// If the peer is writing, we must wait until after reads are completed for that peer before we can read. So // If the peer is writing, we must wait until after reads are completed for that peer before we can read. So
// we keep track of the task, and coordinate later that our read can't happen until the peer is done. // we keep track of the task, and coordinate later that our read can't happen until the peer is done.
final Runnable finishPeerReadTask = new Runnable() { final Runnable finishPeerReadTask = () -> finishPeerRead0(peer);
@Override
public void run() {
finishPeerRead0(peer);
}
};
try { try {
if (peer.writeInProgress) { if (peer.writeInProgress) {
peer.finishReadFuture = peer.eventLoop().submit(finishPeerReadTask); peer.finishReadFuture = peer.eventLoop().submit(finishPeerReadTask);
@ -470,17 +457,14 @@ public class LocalChannel extends AbstractChannel {
// This ensures that if both channels are on the same event loop, the peer's channelActive // This ensures that if both channels are on the same event loop, the peer's channelActive
// event is triggered *after* this channel's channelRegistered event, so that this channel's // event is triggered *after* this channel's channelRegistered event, so that this channel's
// pipeline is fully initialized by ChannelInitializer before any channelRead events. // pipeline is fully initialized by ChannelInitializer before any channelRead events.
peer.eventLoop().execute(new Runnable() { peer.eventLoop().execute(() -> {
@Override ChannelPromise promise = peer.connectPromise;
public void run() {
ChannelPromise promise = peer.connectPromise;
// Only trigger fireChannelActive() if the promise was not null and was not completed yet. // Only trigger fireChannelActive() if the promise was not null and was not completed yet.
// connectPromise may be set to null if doClose() was called in the meantime. // connectPromise may be set to null if doClose() was called in the meantime.
if (promise != null && promise.trySuccess()) { if (promise != null && promise.trySuccess()) {
peer.pipeline().fireChannelActive(); peer.pipeline().fireChannelActive();
peer.readIfIsAutoRead(); peer.readIfIsAutoRead();
}
} }
}); });
} }

View File

@ -38,12 +38,7 @@ public final class LocalHandler implements IoHandler {
* Returns a new {@link IoHandlerFactory} that creates {@link LocalHandler} instances. * Returns a new {@link IoHandlerFactory} that creates {@link LocalHandler} instances.
*/ */
public static IoHandlerFactory newFactory() { public static IoHandlerFactory newFactory() {
return new IoHandlerFactory() { return LocalHandler::new;
@Override
public IoHandler newHandler() {
return new LocalHandler();
}
};
} }
private static LocalChannelUnsafe cast(Channel channel) { private static LocalChannelUnsafe cast(Channel channel) {

View File

@ -115,12 +115,7 @@ public class LocalServerChannel extends AbstractServerChannel {
if (eventLoop().inEventLoop()) { if (eventLoop().inEventLoop()) {
serve0(child); serve0(child);
} else { } else {
eventLoop().execute(new Runnable() { eventLoop().execute(() -> serve0(child));
@Override
public void run() {
serve0(child);
}
});
} }
return child; return child;
} }

View File

@ -47,13 +47,10 @@ public abstract class AbstractNioByteChannel extends AbstractNioChannel {
" (expected: " + StringUtil.simpleClassName(ByteBuf.class) + ", " + " (expected: " + StringUtil.simpleClassName(ByteBuf.class) + ", " +
StringUtil.simpleClassName(FileRegion.class) + ')'; StringUtil.simpleClassName(FileRegion.class) + ')';
private final Runnable flushTask = new Runnable() { private final Runnable flushTask = () -> {
@Override // Calling flush0 directly to ensure we not try to flush messages that were added via write(...) in the
public void run() { // meantime.
// Calling flush0 directly to ensure we not try to flush messages that were added via write(...) in the ((AbstractNioUnsafe) unsafe()).flush0();
// meantime.
((AbstractNioUnsafe) unsafe()).flush0();
}
}; };
private boolean inputClosedSeenErrorOnRead; private boolean inputClosedSeenErrorOnRead;

View File

@ -57,12 +57,7 @@ public abstract class AbstractNioChannel extends AbstractChannel {
protected final int readInterestOp; protected final int readInterestOp;
volatile SelectionKey selectionKey; volatile SelectionKey selectionKey;
boolean readPending; boolean readPending;
private final Runnable clearReadPendingRunnable = new Runnable() { private final Runnable clearReadPendingRunnable = this::clearReadPending0;
@Override
public void run() {
clearReadPending0();
}
};
/** /**
* The future of the current connection attempt. If not null, subsequent * The future of the current connection attempt. If not null, subsequent
@ -142,12 +137,7 @@ public abstract class AbstractNioChannel extends AbstractChannel {
if (eventLoop.inEventLoop()) { if (eventLoop.inEventLoop()) {
setReadPending0(readPending); setReadPending0(readPending);
} else { } else {
eventLoop.execute(new Runnable() { eventLoop.execute(() -> setReadPending0(readPending));
@Override
public void run() {
setReadPending0(readPending);
}
});
} }
} else { } else {
// Best effort if we are not registered yet clear readPending. // Best effort if we are not registered yet clear readPending.
@ -255,29 +245,23 @@ public abstract class AbstractNioChannel extends AbstractChannel {
// Schedule connect timeout. // Schedule connect timeout.
int connectTimeoutMillis = config().getConnectTimeoutMillis(); int connectTimeoutMillis = config().getConnectTimeoutMillis();
if (connectTimeoutMillis > 0) { if (connectTimeoutMillis > 0) {
connectTimeoutFuture = eventLoop().schedule(new Runnable() { connectTimeoutFuture = eventLoop().schedule(() -> {
@Override ChannelPromise connectPromise = AbstractNioChannel.this.connectPromise;
public void run() { ConnectTimeoutException cause =
ChannelPromise connectPromise = AbstractNioChannel.this.connectPromise; new ConnectTimeoutException("connection timed out: " + remoteAddress);
ConnectTimeoutException cause = if (connectPromise != null && connectPromise.tryFailure(cause)) {
new ConnectTimeoutException("connection timed out: " + remoteAddress); close(voidPromise());
if (connectPromise != null && connectPromise.tryFailure(cause)) {
close(voidPromise());
}
} }
}, connectTimeoutMillis, TimeUnit.MILLISECONDS); }, connectTimeoutMillis, TimeUnit.MILLISECONDS);
} }
promise.addListener(new ChannelFutureListener() { promise.addListener((ChannelFutureListener) future -> {
@Override if (future.isCancelled()) {
public void operationComplete(ChannelFuture future) throws Exception { if (connectTimeoutFuture != null) {
if (future.isCancelled()) { connectTimeoutFuture.cancel(false);
if (connectTimeoutFuture != null) {
connectTimeoutFuture.cancel(false);
}
connectPromise = null;
close(voidPromise());
} }
connectPromise = null;
close(voidPromise());
} }
}); });
} }

View File

@ -67,12 +67,7 @@ public final class NioHandler implements IoHandler {
private static final int MIN_PREMATURE_SELECTOR_RETURNS = 3; private static final int MIN_PREMATURE_SELECTOR_RETURNS = 3;
private static final int SELECTOR_AUTO_REBUILD_THRESHOLD; private static final int SELECTOR_AUTO_REBUILD_THRESHOLD;
private final IntSupplier selectNowSupplier = new IntSupplier() { private final IntSupplier selectNowSupplier = this::selectNow;
@Override
public int get() throws Exception {
return selectNow();
}
};
// Workaround for JDK NIO bug. // Workaround for JDK NIO bug.
// //
@ -84,12 +79,9 @@ public final class NioHandler implements IoHandler {
final String bugLevel = SystemPropertyUtil.get(key); final String bugLevel = SystemPropertyUtil.get(key);
if (bugLevel == null) { if (bugLevel == null) {
try { try {
AccessController.doPrivileged(new PrivilegedAction<Void>() { AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
@Override System.setProperty(key, "");
public Void run() { return null;
System.setProperty(key, "");
return null;
}
}); });
} catch (final SecurityException e) { } catch (final SecurityException e) {
logger.debug("Unable to get/set System Property: " + key, e); logger.debug("Unable to get/set System Property: " + key, e);
@ -147,12 +139,7 @@ public final class NioHandler implements IoHandler {
* Returns a new {@link IoHandlerFactory} that creates {@link NioHandler} instances. * Returns a new {@link IoHandlerFactory} that creates {@link NioHandler} instances.
*/ */
public static IoHandlerFactory newFactory() { public static IoHandlerFactory newFactory() {
return new IoHandlerFactory() { return NioHandler::new;
@Override
public IoHandler newHandler() {
return new NioHandler();
}
};
} }
/** /**
@ -162,12 +149,7 @@ public final class NioHandler implements IoHandler {
final SelectStrategyFactory selectStrategyFactory) { final SelectStrategyFactory selectStrategyFactory) {
ObjectUtil.checkNotNull(selectorProvider, "selectorProvider"); ObjectUtil.checkNotNull(selectorProvider, "selectorProvider");
ObjectUtil.checkNotNull(selectStrategyFactory, "selectStrategyFactory"); ObjectUtil.checkNotNull(selectStrategyFactory, "selectStrategyFactory");
return new IoHandlerFactory() { return () -> new NioHandler(selectorProvider, selectStrategyFactory.newSelectStrategy());
@Override
public IoHandler newHandler() {
return new NioHandler(selectorProvider, selectStrategyFactory.newSelectStrategy());
}
};
} }
private static final class SelectorTuple { private static final class SelectorTuple {
@ -197,17 +179,14 @@ public final class NioHandler implements IoHandler {
return new SelectorTuple(unwrappedSelector); return new SelectorTuple(unwrappedSelector);
} }
Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() { Object maybeSelectorImplClass = AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
@Override try {
public Object run() { return Class.forName(
try { "sun.nio.ch.SelectorImpl",
return Class.forName( false,
"sun.nio.ch.SelectorImpl", PlatformDependent.getSystemClassLoader());
false, } catch (Throwable cause) {
PlatformDependent.getSystemClassLoader()); return cause;
} catch (Throwable cause) {
return cause;
}
} }
}); });
@ -224,45 +203,42 @@ public final class NioHandler implements IoHandler {
final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass; final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet(); final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() { Object maybeException = AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
@Override try {
public Object run() { Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
try { Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
if (PlatformDependent.javaVersion() >= 9 && PlatformDependent.hasUnsafe()) { if (PlatformDependent.javaVersion() >= 9 && PlatformDependent.hasUnsafe()) {
// Let us try to use sun.misc.Unsafe to replace the SelectionKeySet. // Let us try to use sun.misc.Unsafe to replace the SelectionKeySet.
// This allows us to also do this in Java9+ without any extra flags. // This allows us to also do this in Java9+ without any extra flags.
long selectedKeysFieldOffset = PlatformDependent.objectFieldOffset(selectedKeysField); long selectedKeysFieldOffset = PlatformDependent.objectFieldOffset(selectedKeysField);
long publicSelectedKeysFieldOffset = long publicSelectedKeysFieldOffset =
PlatformDependent.objectFieldOffset(publicSelectedKeysField); PlatformDependent.objectFieldOffset(publicSelectedKeysField);
if (selectedKeysFieldOffset != -1 && publicSelectedKeysFieldOffset != -1) { if (selectedKeysFieldOffset != -1 && publicSelectedKeysFieldOffset != -1) {
PlatformDependent.putObject( PlatformDependent.putObject(
unwrappedSelector, selectedKeysFieldOffset, selectedKeySet); unwrappedSelector, selectedKeysFieldOffset, selectedKeySet);
PlatformDependent.putObject( PlatformDependent.putObject(
unwrappedSelector, publicSelectedKeysFieldOffset, selectedKeySet); unwrappedSelector, publicSelectedKeysFieldOffset, selectedKeySet);
return null; return null;
}
// We could not retrieve the offset, lets try reflection as last-resort.
} }
// We could not retrieve the offset, lets try reflection as last-resort.
Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true);
if (cause != null) {
return cause;
}
cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
if (cause != null) {
return cause;
}
selectedKeysField.set(unwrappedSelector, selectedKeySet);
publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
return null;
} catch (NoSuchFieldException | IllegalAccessException e) {
return e;
} }
Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true);
if (cause != null) {
return cause;
}
cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
if (cause != null) {
return cause;
}
selectedKeysField.set(unwrappedSelector, selectedKeySet);
publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
return null;
} catch (NoSuchFieldException | IllegalAccessException e) {
return e;
} }
}); });

View File

@ -170,12 +170,7 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
if (loop.inEventLoop()) { if (loop.inEventLoop()) {
((AbstractUnsafe) unsafe()).shutdownOutput(promise); ((AbstractUnsafe) unsafe()).shutdownOutput(promise);
} else { } else {
loop.execute(new Runnable() { loop.execute(() -> ((AbstractUnsafe) unsafe()).shutdownOutput(promise));
@Override
public void run() {
((AbstractUnsafe) unsafe()).shutdownOutput(promise);
}
});
} }
return promise; return promise;
} }
@ -196,12 +191,7 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
if (loop.inEventLoop()) { if (loop.inEventLoop()) {
shutdownInput0(promise); shutdownInput0(promise);
} else { } else {
loop.execute(new Runnable() { loop.execute(() -> shutdownInput0(promise));
@Override
public void run() {
shutdownInput0(promise);
}
});
} }
return promise; return promise;
} }
@ -217,12 +207,8 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
if (shutdownOutputFuture.isDone()) { if (shutdownOutputFuture.isDone()) {
shutdownOutputDone(shutdownOutputFuture, promise); shutdownOutputDone(shutdownOutputFuture, promise);
} else { } else {
shutdownOutputFuture.addListener(new ChannelFutureListener() { shutdownOutputFuture.addListener((ChannelFutureListener) shutdownOutputFuture1 ->
@Override shutdownOutputDone(shutdownOutputFuture1, promise));
public void operationComplete(final ChannelFuture shutdownOutputFuture) throws Exception {
shutdownOutputDone(shutdownOutputFuture, promise);
}
});
} }
return promise; return promise;
} }
@ -232,12 +218,8 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
if (shutdownInputFuture.isDone()) { if (shutdownInputFuture.isDone()) {
shutdownDone(shutdownOutputFuture, shutdownInputFuture, promise); shutdownDone(shutdownOutputFuture, shutdownInputFuture, promise);
} else { } else {
shutdownInputFuture.addListener(new ChannelFutureListener() { shutdownInputFuture.addListener((ChannelFutureListener) shutdownInputFuture1 ->
@Override shutdownDone(shutdownOutputFuture, shutdownInputFuture1, promise));
public void operationComplete(ChannelFuture shutdownInputFuture) throws Exception {
shutdownDone(shutdownOutputFuture, shutdownInputFuture, promise);
}
});
} }
} }

View File

@ -16,8 +16,6 @@
package io.netty.bootstrap; package io.netty.bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
@ -26,18 +24,15 @@ import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise; import io.netty.channel.ChannelPromise;
import io.netty.channel.MultithreadEventLoopGroup;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.ServerChannel; import io.netty.channel.MultithreadEventLoopGroup;
import io.netty.channel.ServerChannelFactory;
import io.netty.channel.local.LocalAddress; import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalChannel; import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalHandler; import io.netty.channel.local.LocalHandler;
import io.netty.channel.local.LocalServerChannel; import io.netty.channel.local.LocalServerChannel;
import io.netty.resolver.AbstractAddressResolver;
import io.netty.resolver.AddressResolver; import io.netty.resolver.AddressResolver;
import io.netty.resolver.AddressResolverGroup; import io.netty.resolver.AddressResolverGroup;
import io.netty.resolver.AbstractAddressResolver;
import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.Promise; import io.netty.util.concurrent.Promise;
@ -55,8 +50,14 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.*; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BootstrapTest { public class BootstrapTest {
@ -88,18 +89,12 @@ public class BootstrapTest {
// Try to bind from each other. // Try to bind from each other.
for (int i = 0; i < 1024; i ++) { for (int i = 0; i < 1024; i ++) {
bindFutures.add(groupA.next().submit(new Runnable() { bindFutures.add(groupA.next().submit(() -> {
@Override bootstrapB.bind(LocalAddress.ANY);
public void run() {
bootstrapB.bind(LocalAddress.ANY);
}
})); }));
bindFutures.add(groupB.next().submit(new Runnable() { bindFutures.add(groupB.next().submit(() -> {
@Override bootstrapA.bind(LocalAddress.ANY);
public void run() {
bootstrapA.bind(LocalAddress.ANY);
}
})); }));
} }
@ -124,18 +119,12 @@ public class BootstrapTest {
// Try to connect from each other. // Try to connect from each other.
for (int i = 0; i < 1024; i ++) { for (int i = 0; i < 1024; i ++) {
bindFutures.add(groupA.next().submit(new Runnable() { bindFutures.add(groupA.next().submit(() -> {
@Override bootstrapB.connect(LocalAddress.ANY);
public void run() {
bootstrapB.connect(LocalAddress.ANY);
}
})); }));
bindFutures.add(groupB.next().submit(new Runnable() { bindFutures.add(groupB.next().submit(() -> {
@Override bootstrapA.connect(LocalAddress.ANY);
public void run() {
bootstrapA.connect(LocalAddress.ANY);
}
})); }));
} }
@ -159,12 +148,9 @@ public class BootstrapTest {
assertFalse(future.isDone()); assertFalse(future.isDone());
registerHandler.registerPromise().setSuccess(); registerHandler.registerPromise().setSuccess();
final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(); final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
future.addListener(new ChannelFutureListener() { future.addListener((ChannelFutureListener) future1 -> {
@Override queue.add(future1.channel().eventLoop().inEventLoop(Thread.currentThread()));
public void operationComplete(ChannelFuture future) throws Exception { queue.add(future1.isSuccess());
queue.add(future.channel().eventLoop().inEventLoop(Thread.currentThread()));
queue.add(future.isSuccess());
}
}); });
assertTrue(queue.take()); assertTrue(queue.take());
assertTrue(queue.take()); assertTrue(queue.take());
@ -181,10 +167,8 @@ public class BootstrapTest {
try { try {
ServerBootstrap bootstrap = new ServerBootstrap(); ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(group); bootstrap.group(group);
bootstrap.channelFactory(new ServerChannelFactory<ServerChannel>() { bootstrap.channelFactory((eventLoop, childEventLoopGroup) ->
@Override new LocalServerChannel(eventLoop, childEventLoopGroup) {
public ServerChannel newChannel(EventLoop eventLoop, EventLoopGroup childEventLoopGroup) {
return new LocalServerChannel(eventLoop, childEventLoopGroup) {
@Override @Override
public ChannelFuture bind(SocketAddress localAddress) { public ChannelFuture bind(SocketAddress localAddress) {
// Close the Channel to emulate what NIO and others impl do on bind failure // Close the Channel to emulate what NIO and others impl do on bind failure
@ -200,9 +184,7 @@ public class BootstrapTest {
close(); close();
return promise.setFailure(new SocketException()); return promise.setFailure(new SocketException());
} }
}; });
}
});
bootstrap.childHandler(new DummyHandler()); bootstrap.childHandler(new DummyHandler());
bootstrap.handler(registerHandler); bootstrap.handler(registerHandler);
bootstrap.localAddress(new LocalAddress("1")); bootstrap.localAddress(new LocalAddress("1"));
@ -210,12 +192,9 @@ public class BootstrapTest {
assertFalse(future.isDone()); assertFalse(future.isDone());
registerHandler.registerPromise().setSuccess(); registerHandler.registerPromise().setSuccess();
final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(); final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
future.addListener(new ChannelFutureListener() { future.addListener((ChannelFutureListener) future1 -> {
@Override queue.add(future1.channel().eventLoop().inEventLoop(Thread.currentThread()));
public void operationComplete(ChannelFuture future) throws Exception { queue.add(future1.isSuccess());
queue.add(future.channel().eventLoop().inEventLoop(Thread.currentThread()));
queue.add(future.isSuccess());
}
}); });
assertTrue(queue.take()); assertTrue(queue.take());
assertFalse(queue.take()); assertFalse(queue.take());
@ -291,12 +270,9 @@ public class BootstrapTest {
final Bootstrap bootstrap = new Bootstrap() final Bootstrap bootstrap = new Bootstrap()
.handler(dummyHandler) .handler(dummyHandler)
.group(groupA) .group(groupA)
.channelFactory(new ChannelFactory<Channel>() { .channelFactory(eventLoop -> {
@Override throw exception;
public Channel newChannel(EventLoop eventLoop) { });
throw exception;
}
});
ChannelFuture connectFuture = bootstrap.connect(LocalAddress.ANY); ChannelFuture connectFuture = bootstrap.connect(LocalAddress.ANY);
@ -316,12 +292,9 @@ public class BootstrapTest {
registerPromise = promise; registerPromise = promise;
latch.countDown(); latch.countDown();
ChannelPromise newPromise = ctx.newPromise(); ChannelPromise newPromise = ctx.newPromise();
newPromise.addListener(new ChannelFutureListener() { newPromise.addListener((ChannelFutureListener) future -> {
@Override if (!future.isSuccess()) {
public void operationComplete(ChannelFuture future) throws Exception { registerPromise.tryFailure(future.cause());
if (!future.isSuccess()) {
registerPromise.tryFailure(future.cause());
}
} }
}); });
super.register(ctx, newPromise); super.register(ctx, newPromise);
@ -356,14 +329,11 @@ public class BootstrapTest {
@Override @Override
protected void doResolve( protected void doResolve(
final SocketAddress unresolvedAddress, final Promise<SocketAddress> promise) { final SocketAddress unresolvedAddress, final Promise<SocketAddress> promise) {
executor().execute(new Runnable() { executor().execute(() -> {
@Override if (success) {
public void run() { promise.setSuccess(unresolvedAddress);
if (success) { } else {
promise.setSuccess(unresolvedAddress); promise.setFailure(new UnknownHostException(unresolvedAddress.toString()));
} else {
promise.setFailure(new UnknownHostException(unresolvedAddress.toString()));
}
} }
}); });
} }
@ -372,14 +342,11 @@ public class BootstrapTest {
protected void doResolveAll( protected void doResolveAll(
final SocketAddress unresolvedAddress, final Promise<List<SocketAddress>> promise) final SocketAddress unresolvedAddress, final Promise<List<SocketAddress>> promise)
throws Exception { throws Exception {
executor().execute(new Runnable() { executor().execute(() -> {
@Override if (success) {
public void run() { promise.setSuccess(Collections.singletonList(unresolvedAddress));
if (success) { } else {
promise.setSuccess(Collections.singletonList(unresolvedAddress)); promise.setFailure(new UnknownHostException(unresolvedAddress.toString()));
} else {
promise.setFailure(new UnknownHostException(unresolvedAddress.toString()));
}
} }
}); });
} }

View File

@ -51,12 +51,9 @@ public class AbstractChannelTest {
when(eventLoop.inEventLoop()).thenReturn(true); when(eventLoop.inEventLoop()).thenReturn(true);
when(eventLoop.unsafe()).thenReturn(mock(EventLoop.Unsafe.class)); when(eventLoop.unsafe()).thenReturn(mock(EventLoop.Unsafe.class));
doAnswer(new Answer() { doAnswer(invocationOnMock -> {
@Override ((Runnable) invocationOnMock.getArgument(0)).run();
public Object answer(InvocationOnMock invocationOnMock) throws Throwable { return null;
((Runnable) invocationOnMock.getArgument(0)).run();
return null;
}
}).when(eventLoop).execute(any(Runnable.class)); }).when(eventLoop).execute(any(Runnable.class));
final TestChannel channel = new TestChannel(eventLoop); final TestChannel channel = new TestChannel(eventLoop);

View File

@ -146,11 +146,8 @@ public class ChannelInitializerTest {
try { try {
// Execute some task on the EventLoop and wait until its done to be sure all handlers are added to the // Execute some task on the EventLoop and wait until its done to be sure all handlers are added to the
// pipeline. // pipeline.
channel.eventLoop().submit(new Runnable() { channel.eventLoop().submit(() -> {
@Override // NOOP
public void run() {
// NOOP
}
}).syncUninterruptibly(); }).syncUninterruptibly();
Iterator<Map.Entry<String, ChannelHandler>> handlers = channel.pipeline().iterator(); Iterator<Map.Entry<String, ChannelHandler>> handlers = channel.pipeline().iterator();
assertSame(handler1, handlers.next().getValue()); assertSame(handler1, handlers.next().getValue());
@ -186,11 +183,8 @@ public class ChannelInitializerTest {
try { try {
// Execute some task on the EventLoop and wait until its done to be sure all handlers are added to the // Execute some task on the EventLoop and wait until its done to be sure all handlers are added to the
// pipeline. // pipeline.
channel.eventLoop().submit(new Runnable() { channel.eventLoop().submit(() -> {
@Override // NOOP
public void run() {
// NOOP
}
}).syncUninterruptibly(); }).syncUninterruptibly();
assertEquals(1, initChannelCalled.get()); assertEquals(1, initChannelCalled.get());
assertEquals(2, registeredCalled.get()); assertEquals(2, registeredCalled.get());

View File

@ -424,25 +424,19 @@ public class ChannelOutboundBufferTest {
final CountDownLatch executeLatch = new CountDownLatch(1); final CountDownLatch executeLatch = new CountDownLatch(1);
final CountDownLatch runLatch = new CountDownLatch(1); final CountDownLatch runLatch = new CountDownLatch(1);
executor.execute(new Runnable() { executor.execute(() -> {
@Override try {
public void run() { runLatch.countDown();
try { executeLatch.await();
runLatch.countDown(); } catch (InterruptedException e) {
executeLatch.await(); Thread.currentThread().interrupt();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
} }
}); });
runLatch.await(); runLatch.await();
executor.execute(new Runnable() { executor.execute(() -> {
@Override // Will not be executed but ensure the pending count is 1.
public void run() {
// Will not be executed but ensure the pending count is 1.
}
}); });
assertEquals(1, executor.pendingTasks()); assertEquals(1, executor.pendingTasks());

View File

@ -53,12 +53,9 @@ public class CoalescingBufferQueueTest {
channel = new EmbeddedChannel(); channel = new EmbeddedChannel();
writeQueue = new CoalescingBufferQueue(channel, 16, true); writeQueue = new CoalescingBufferQueue(channel, 16, true);
catPromise = newPromise(); catPromise = newPromise();
mouseListener = new ChannelFutureListener() { mouseListener = future -> {
@Override mouseDone = true;
public void operationComplete(ChannelFuture future) throws Exception { mouseSuccess = future.isSuccess();
mouseDone = true;
mouseSuccess = future.isSuccess();
}
}; };
emptyPromise = newPromise(); emptyPromise = newPromise();
voidPromise = channel.voidPromise(); voidPromise = channel.voidPromise();

View File

@ -368,17 +368,14 @@ public class DefaultChannelPipelineTest {
// Add handler. // Add handler.
p.addFirst(handler.name, handler); p.addFirst(handler.name, handler);
self.eventLoop().execute(new Runnable() { self.eventLoop().execute(() -> {
@Override // Validate handler life-cycle methods called.
public void run() { handler.validate(true, false);
// Validate handler life-cycle methods called.
handler.validate(true, false);
// Store handler into the list. // Store handler into the list.
handlers.add(handler); handlers.add(handler);
addLatch.countDown(); addLatch.countDown();
}
}); });
} }
addLatch.await(); addLatch.await();
@ -391,13 +388,10 @@ public class DefaultChannelPipelineTest {
for (final LifeCycleAwareTestHandler handler : handlers) { for (final LifeCycleAwareTestHandler handler : handlers) {
assertSame(handler, p.remove(handler.name)); assertSame(handler, p.remove(handler.name));
self.eventLoop().execute(new Runnable() { self.eventLoop().execute(() -> {
@Override // Validate handler life-cycle methods called.
public void run() { handler.validate(true, true);
// Validate handler life-cycle methods called. removeLatch.countDown();
handler.validate(true, true);
removeLatch.countDown();
}
}); });
} }
removeLatch.await(); removeLatch.await();
@ -410,17 +404,14 @@ public class DefaultChannelPipelineTest {
setUp(handler1, handler2); setUp(handler1, handler2);
self.eventLoop().submit(new Runnable() { self.eventLoop().submit(() -> {
@Override ChannelPipeline p = self.pipeline();
public void run() { handler1.inboundBuffer.add(8);
ChannelPipeline p = self.pipeline(); assertEquals(8, handler1.inboundBuffer.peek());
handler1.inboundBuffer.add(8); assertTrue(handler2.inboundBuffer.isEmpty());
assertEquals(8, handler1.inboundBuffer.peek()); p.remove(handler1);
assertTrue(handler2.inboundBuffer.isEmpty()); assertEquals(1, handler2.inboundBuffer.size());
p.remove(handler1); assertEquals(8, handler2.inboundBuffer.peek());
assertEquals(1, handler2.inboundBuffer.size());
assertEquals(8, handler2.inboundBuffer.peek());
}
}).sync(); }).sync();
} }
@ -431,17 +422,14 @@ public class DefaultChannelPipelineTest {
setUp(handler1, handler2); setUp(handler1, handler2);
self.eventLoop().submit(new Runnable() { self.eventLoop().submit(() -> {
@Override ChannelPipeline p = self.pipeline();
public void run() { handler2.outboundBuffer.add(8);
ChannelPipeline p = self.pipeline(); assertEquals(8, handler2.outboundBuffer.peek());
handler2.outboundBuffer.add(8); assertTrue(handler1.outboundBuffer.isEmpty());
assertEquals(8, handler2.outboundBuffer.peek()); p.remove(handler2);
assertTrue(handler1.outboundBuffer.isEmpty()); assertEquals(1, handler1.outboundBuffer.size());
p.remove(handler2); assertEquals(8, handler1.outboundBuffer.peek());
assertEquals(1, handler1.outboundBuffer.size());
assertEquals(8, handler1.outboundBuffer.peek());
}
}).sync(); }).sync();
} }
@ -452,16 +440,13 @@ public class DefaultChannelPipelineTest {
setUp(handler1); setUp(handler1);
self.eventLoop().submit(new Runnable() { self.eventLoop().submit(() -> {
@Override ChannelPipeline p = self.pipeline();
public void run() { handler1.outboundBuffer.add(8);
ChannelPipeline p = self.pipeline(); assertEquals(8, handler1.outboundBuffer.peek());
handler1.outboundBuffer.add(8); assertTrue(handler2.outboundBuffer.isEmpty());
assertEquals(8, handler1.outboundBuffer.peek()); p.replace(handler1, "handler2", handler2);
assertTrue(handler2.outboundBuffer.isEmpty()); assertEquals(8, handler2.outboundBuffer.peek());
p.replace(handler1, "handler2", handler2);
assertEquals(8, handler2.outboundBuffer.peek());
}
}).sync(); }).sync();
} }
@ -472,22 +457,19 @@ public class DefaultChannelPipelineTest {
setUp(handler1); setUp(handler1);
self.eventLoop().submit(new Runnable() { self.eventLoop().submit(() -> {
@Override ChannelPipeline p = self.pipeline();
public void run() { handler1.inboundBuffer.add(8);
ChannelPipeline p = self.pipeline(); handler1.outboundBuffer.add(8);
handler1.inboundBuffer.add(8);
handler1.outboundBuffer.add(8);
assertEquals(8, handler1.inboundBuffer.peek()); assertEquals(8, handler1.inboundBuffer.peek());
assertEquals(8, handler1.outboundBuffer.peek()); assertEquals(8, handler1.outboundBuffer.peek());
assertTrue(handler2.inboundBuffer.isEmpty()); assertTrue(handler2.inboundBuffer.isEmpty());
assertTrue(handler2.outboundBuffer.isEmpty()); assertTrue(handler2.outboundBuffer.isEmpty());
p.replace(handler1, "handler2", handler2); p.replace(handler1, "handler2", handler2);
assertEquals(8, handler2.outboundBuffer.peek()); assertEquals(8, handler2.outboundBuffer.peek());
assertEquals(8, handler2.inboundBuffer.peek()); assertEquals(8, handler2.inboundBuffer.peek());
}
}).sync(); }).sync();
} }
@ -499,23 +481,20 @@ public class DefaultChannelPipelineTest {
setUp(handler1, handler2, handler3); setUp(handler1, handler2, handler3);
self.eventLoop().submit(new Runnable() { self.eventLoop().submit(() -> {
@Override ChannelPipeline p = self.pipeline();
public void run() { handler2.inboundBuffer.add(8);
ChannelPipeline p = self.pipeline(); handler2.outboundBuffer.add(8);
handler2.inboundBuffer.add(8);
handler2.outboundBuffer.add(8);
assertEquals(8, handler2.inboundBuffer.peek()); assertEquals(8, handler2.inboundBuffer.peek());
assertEquals(8, handler2.outboundBuffer.peek()); assertEquals(8, handler2.outboundBuffer.peek());
assertEquals(0, handler1.outboundBuffer.size()); assertEquals(0, handler1.outboundBuffer.size());
assertEquals(0, handler3.inboundBuffer.size()); assertEquals(0, handler3.inboundBuffer.size());
p.remove(handler2); p.remove(handler2);
assertEquals(8, handler3.inboundBuffer.peek()); assertEquals(8, handler3.inboundBuffer.peek());
assertEquals(8, handler1.outboundBuffer.peek()); assertEquals(8, handler1.outboundBuffer.peek());
}
}).sync(); }).sync();
} }
@ -870,12 +849,7 @@ public class DefaultChannelPipelineTest {
@Override @Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
// Execute this later so we are sure the exception is handled first. // Execute this later so we are sure the exception is handled first.
ctx.executor().execute(new Runnable() { ctx.executor().execute(latch::countDown);
@Override
public void run() {
latch.countDown();
}
});
throw exceptionRemoved; throw exceptionRemoved;
} }
}); });
@ -986,34 +960,31 @@ public class DefaultChannelPipelineTest {
try { try {
final Object event = new Object(); final Object event = new Object();
final Promise<Object> promise = ImmediateEventExecutor.INSTANCE.newPromise(); final Promise<Object> promise = ImmediateEventExecutor.INSTANCE.newPromise();
pipeline1.channel().register().addListener(new ChannelFutureListener() { pipeline1.channel().register().addListener((ChannelFutureListener) future -> {
@Override ChannelPipeline pipeline = future.channel().pipeline();
public void operationComplete(ChannelFuture future) throws Exception { final AtomicBoolean handlerAddedCalled = new AtomicBoolean();
ChannelPipeline pipeline = future.channel().pipeline(); pipeline.addLast(new ChannelInboundHandlerAdapter() {
final AtomicBoolean handlerAddedCalled = new AtomicBoolean(); @Override
pipeline.addLast(new ChannelInboundHandlerAdapter() { public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
@Override handlerAddedCalled.set(true);
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
handlerAddedCalled.set(true);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
promise.setSuccess(event);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
promise.setFailure(cause);
}
});
if (!handlerAddedCalled.get()) {
promise.setFailure(new AssertionError("handlerAdded(...) should have been called"));
return;
} }
// This event must be captured by the added handler.
pipeline.fireUserEventTriggered(event); @Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
promise.setSuccess(event);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
promise.setFailure(cause);
}
});
if (!handlerAddedCalled.get()) {
promise.setFailure(new AssertionError("handlerAdded(...) should have been called"));
return;
} }
// This event must be captured by the added handler.
pipeline.fireUserEventTriggered(event);
}); });
assertSame(event, promise.syncUninterruptibly().getNow()); assertSame(event, promise.syncUninterruptibly().getNow());
} finally { } finally {
@ -1184,11 +1155,8 @@ public class DefaultChannelPipelineTest {
pipeline.channel().closeFuture().syncUninterruptibly(); pipeline.channel().closeFuture().syncUninterruptibly();
// Schedule something on the EventLoop to ensure all other scheduled tasks had a chance to complete. // Schedule something on the EventLoop to ensure all other scheduled tasks had a chance to complete.
pipeline.channel().eventLoop().submit(new Runnable() { pipeline.channel().eventLoop().submit(() -> {
@Override // NOOP
public void run() {
// NOOP
}
}).syncUninterruptibly(); }).syncUninterruptibly();
Error error = errorRef.get(); Error error = errorRef.get();
if (error != null) { if (error != null) {
@ -1646,33 +1614,30 @@ public class DefaultChannelPipelineTest {
final Object writeObject = new Object(); final Object writeObject = new Object();
final CountDownLatch doneLatch = new CountDownLatch(1); final CountDownLatch doneLatch = new CountDownLatch(1);
Runnable r = new Runnable() { Runnable r = () -> {
@Override pipeline.addLast(new ChannelInboundHandlerAdapter() {
public void run() { @Override
pipeline.addLast(new ChannelInboundHandlerAdapter() { public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
@Override if (evt == userEvent) {
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { ctx.write(writeObject);
if (evt == userEvent) {
ctx.write(writeObject);
}
ctx.fireUserEventTriggered(evt);
}
});
pipeline.addFirst(new ChannelDuplexHandler() {
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
ctx.fireUserEventTriggered(userEvent);
} }
ctx.fireUserEventTriggered(evt);
}
});
pipeline.addFirst(new ChannelDuplexHandler() {
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
ctx.fireUserEventTriggered(userEvent);
}
@Override @Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
if (msg == writeObject) { if (msg == writeObject) {
doneLatch.countDown(); doneLatch.countDown();
}
ctx.write(msg, promise);
} }
}); ctx.write(msg, promise);
} }
});
}; };
if (executeInEventLoop) { if (executeInEventLoop) {

View File

@ -40,12 +40,7 @@ public class PendingWriteQueueTest {
assertFalse("Should not be writable anymore", ctx.channel().isWritable()); assertFalse("Should not be writable anymore", ctx.channel().isWritable());
ChannelFuture future = queue.removeAndWrite(); ChannelFuture future = queue.removeAndWrite();
future.addListener(new ChannelFutureListener() { future.addListener((ChannelFutureListener) future1 -> assertQueueEmpty(queue));
@Override
public void operationComplete(ChannelFuture future) throws Exception {
assertQueueEmpty(queue);
}
});
super.flush(ctx); super.flush(ctx);
} }
}, 1); }, 1);
@ -59,12 +54,7 @@ public class PendingWriteQueueTest {
assertFalse("Should not be writable anymore", ctx.channel().isWritable()); assertFalse("Should not be writable anymore", ctx.channel().isWritable());
ChannelFuture future = queue.removeAndWriteAll(); ChannelFuture future = queue.removeAndWriteAll();
future.addListener(new ChannelFutureListener() { future.addListener((ChannelFutureListener) future1 -> assertQueueEmpty(queue));
@Override
public void operationComplete(ChannelFuture future) throws Exception {
assertQueueEmpty(queue);
}
});
super.flush(ctx); super.flush(ctx);
} }
}, 3); }, 3);
@ -209,12 +199,7 @@ public class PendingWriteQueueTest {
final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext()); final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext());
ChannelPromise promise = channel.newPromise(); ChannelPromise promise = channel.newPromise();
promise.addListener(new ChannelFutureListener() { promise.addListener((ChannelFutureListener) future -> queue.removeAndFailAll(new IllegalStateException()));
@Override
public void operationComplete(ChannelFuture future) throws Exception {
queue.removeAndFailAll(new IllegalStateException());
}
});
queue.add(1L, promise); queue.add(1L, promise);
ChannelPromise promise2 = channel.newPromise(); ChannelPromise promise2 = channel.newPromise();
@ -241,12 +226,7 @@ public class PendingWriteQueueTest {
ChannelPromise promise = channel.newPromise(); ChannelPromise promise = channel.newPromise();
final ChannelPromise promise3 = channel.newPromise(); final ChannelPromise promise3 = channel.newPromise();
promise.addListener(new ChannelFutureListener() { promise.addListener((ChannelFutureListener) future -> queue.add(3L, promise3));
@Override
public void operationComplete(ChannelFuture future) {
queue.add(3L, promise3);
}
});
queue.add(1L, promise); queue.add(1L, promise);
ChannelPromise promise2 = channel.newPromise(); ChannelPromise promise2 = channel.newPromise();
queue.add(2L, promise2); queue.add(2L, promise2);
@ -296,28 +276,15 @@ public class PendingWriteQueueTest {
ChannelPromise promise = channel.newPromise(); ChannelPromise promise = channel.newPromise();
final ChannelPromise promise3 = channel.newPromise(); final ChannelPromise promise3 = channel.newPromise();
promise3.addListener(new ChannelFutureListener() { promise3.addListener((ChannelFutureListener) future -> failOrder.add(3));
@Override promise.addListener((ChannelFutureListener) future -> {
public void operationComplete(ChannelFuture future) throws Exception { failOrder.add(1);
failOrder.add(3); queue.add(3L, promise3);
}
});
promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
failOrder.add(1);
queue.add(3L, promise3);
}
}); });
queue.add(1L, promise); queue.add(1L, promise);
ChannelPromise promise2 = channel.newPromise(); ChannelPromise promise2 = channel.newPromise();
promise2.addListener(new ChannelFutureListener() { promise2.addListener((ChannelFutureListener) future -> failOrder.add(2));
@Override
public void operationComplete(ChannelFuture future) throws Exception {
failOrder.add(2);
}
});
queue.add(2L, promise2); queue.add(2L, promise2);
queue.removeAndFailAll(new Exception()); queue.removeAndFailAll(new Exception());
assertTrue(promise.isDone()); assertTrue(promise.isDone());
@ -338,12 +305,7 @@ public class PendingWriteQueueTest {
final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext()); final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext());
ChannelPromise promise = channel.newPromise(); ChannelPromise promise = channel.newPromise();
promise.addListener(new ChannelFutureListener() { promise.addListener((ChannelFutureListener) future -> queue.removeAndWriteAll());
@Override
public void operationComplete(ChannelFuture future) throws Exception {
queue.removeAndWriteAll();
}
});
queue.add(1L, promise); queue.add(1L, promise);
ChannelPromise promise2 = channel.newPromise(); ChannelPromise promise2 = channel.newPromise();

View File

@ -226,12 +226,7 @@ public class ReentrantChannelTest extends BaseChannelTest {
@Override @Override
public void write(final ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { public void write(final ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
promise.addListener(new GenericFutureListener<Future<? super Void>>() { promise.addListener(future -> ctx.channel().close());
@Override
public void operationComplete(Future<? super Void> future) throws Exception {
ctx.channel().close();
}
});
super.write(ctx, msg, promise); super.write(ctx, msg, promise);
ctx.channel().flush(); ctx.channel().flush();
} }

View File

@ -46,10 +46,7 @@ import static org.junit.Assert.*;
public class SingleThreadEventLoopTest { public class SingleThreadEventLoopTest {
private static final Runnable NOOP = new Runnable() { private static final Runnable NOOP = () -> { };
@Override
public void run() { }
};
private SingleThreadEventLoopA loopA; private SingleThreadEventLoopA loopA;
private SingleThreadEventLoopB loopB; private SingleThreadEventLoopB loopB;
@ -98,12 +95,7 @@ public class SingleThreadEventLoopTest {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void shutdownAfterStart() throws Exception { public void shutdownAfterStart() throws Exception {
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
loopA.execute(new Runnable() { loopA.execute(latch::countDown);
@Override
public void run() {
latch.countDown();
}
});
// Wait for the event loop thread to start. // Wait for the event loop thread to start.
latch.await(); latch.await();
@ -142,12 +134,7 @@ public class SingleThreadEventLoopTest {
private static void testScheduleTask(EventLoop loopA) throws InterruptedException, ExecutionException { private static void testScheduleTask(EventLoop loopA) throws InterruptedException, ExecutionException {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
final AtomicLong endTime = new AtomicLong(); final AtomicLong endTime = new AtomicLong();
loopA.schedule(new Runnable() { loopA.schedule(() -> endTime.set(System.nanoTime()), 500, TimeUnit.MILLISECONDS).get();
@Override
public void run() {
endTime.set(System.nanoTime());
}
}, 500, TimeUnit.MILLISECONDS).get();
assertThat(endTime.get() - startTime, assertThat(endTime.get() - startTime,
is(greaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(500)))); is(greaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(500))));
} }
@ -166,17 +153,14 @@ public class SingleThreadEventLoopTest {
final Queue<Long> timestamps = new LinkedBlockingQueue<>(); final Queue<Long> timestamps = new LinkedBlockingQueue<>();
final int expectedTimeStamps = 5; final int expectedTimeStamps = 5;
final CountDownLatch allTimeStampsLatch = new CountDownLatch(expectedTimeStamps); final CountDownLatch allTimeStampsLatch = new CountDownLatch(expectedTimeStamps);
ScheduledFuture<?> f = loopA.scheduleAtFixedRate(new Runnable() { ScheduledFuture<?> f = loopA.scheduleAtFixedRate(() -> {
@Override timestamps.add(System.nanoTime());
public void run() { try {
timestamps.add(System.nanoTime()); Thread.sleep(50);
try { } catch (InterruptedException e) {
Thread.sleep(50); // Ignore
} catch (InterruptedException e) {
// Ignore
}
allTimeStampsLatch.countDown();
} }
allTimeStampsLatch.countDown();
}, 100, 100, TimeUnit.MILLISECONDS); }, 100, 100, TimeUnit.MILLISECONDS);
allTimeStampsLatch.await(); allTimeStampsLatch.await();
assertTrue(f.cancel(true)); assertTrue(f.cancel(true));
@ -214,20 +198,17 @@ public class SingleThreadEventLoopTest {
final Queue<Long> timestamps = new LinkedBlockingQueue<>(); final Queue<Long> timestamps = new LinkedBlockingQueue<>();
final int expectedTimeStamps = 5; final int expectedTimeStamps = 5;
final CountDownLatch allTimeStampsLatch = new CountDownLatch(expectedTimeStamps); final CountDownLatch allTimeStampsLatch = new CountDownLatch(expectedTimeStamps);
ScheduledFuture<?> f = loopA.scheduleAtFixedRate(new Runnable() { ScheduledFuture<?> f = loopA.scheduleAtFixedRate(() -> {
@Override boolean empty = timestamps.isEmpty();
public void run() { timestamps.add(System.nanoTime());
boolean empty = timestamps.isEmpty(); if (empty) {
timestamps.add(System.nanoTime()); try {
if (empty) { Thread.sleep(401);
try { } catch (InterruptedException e) {
Thread.sleep(401); // Ignore
} catch (InterruptedException e) {
// Ignore
}
} }
allTimeStampsLatch.countDown();
} }
allTimeStampsLatch.countDown();
}, 100, 100, TimeUnit.MILLISECONDS); }, 100, 100, TimeUnit.MILLISECONDS);
allTimeStampsLatch.await(); allTimeStampsLatch.await();
assertTrue(f.cancel(true)); assertTrue(f.cancel(true));
@ -268,17 +249,14 @@ public class SingleThreadEventLoopTest {
final Queue<Long> timestamps = new LinkedBlockingQueue<>(); final Queue<Long> timestamps = new LinkedBlockingQueue<>();
final int expectedTimeStamps = 3; final int expectedTimeStamps = 3;
final CountDownLatch allTimeStampsLatch = new CountDownLatch(expectedTimeStamps); final CountDownLatch allTimeStampsLatch = new CountDownLatch(expectedTimeStamps);
ScheduledFuture<?> f = loopA.scheduleWithFixedDelay(new Runnable() { ScheduledFuture<?> f = loopA.scheduleWithFixedDelay(() -> {
@Override timestamps.add(System.nanoTime());
public void run() { try {
timestamps.add(System.nanoTime()); Thread.sleep(51);
try { } catch (InterruptedException e) {
Thread.sleep(51); // Ignore
} catch (InterruptedException e) {
// Ignore
}
allTimeStampsLatch.countDown();
} }
allTimeStampsLatch.countDown();
}, 100, 100, TimeUnit.MILLISECONDS); }, 100, 100, TimeUnit.MILLISECONDS);
allTimeStampsLatch.await(); allTimeStampsLatch.await();
assertTrue(f.cancel(true)); assertTrue(f.cancel(true));
@ -305,16 +283,13 @@ public class SingleThreadEventLoopTest {
final int NUM_TASKS = 3; final int NUM_TASKS = 3;
final AtomicInteger ranTasks = new AtomicInteger(); final AtomicInteger ranTasks = new AtomicInteger();
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
final Runnable task = new Runnable() { final Runnable task = () -> {
@Override ranTasks.incrementAndGet();
public void run() { while (latch.getCount() > 0) {
ranTasks.incrementAndGet(); try {
while (latch.getCount() > 0) { latch.await();
try { } catch (InterruptedException e) {
latch.await(); // Ignored
} catch (InterruptedException e) {
// Ignored
}
} }
} }
}; };
@ -380,12 +355,7 @@ public class SingleThreadEventLoopTest {
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
Channel ch = new LocalChannel(loopA); Channel ch = new LocalChannel(loopA);
ChannelPromise promise = ch.newPromise(); ChannelPromise promise = ch.newPromise();
promise.addListener(new ChannelFutureListener() { promise.addListener((ChannelFutureListener) future -> latch.countDown());
@Override
public void operationComplete(ChannelFuture future) throws Exception {
latch.countDown();
}
});
// Disable logging temporarily. // Disable logging temporarily.
Logger root = (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); Logger root = (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

View File

@ -22,6 +22,7 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import io.netty.channel.ChannelOutboundInvoker;
import java.nio.channels.ClosedChannelException; import java.nio.channels.ClosedChannelException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Queue; import java.util.Queue;
@ -79,12 +80,7 @@ public class EmbeddedChannelTest {
@Test(timeout = 2000) @Test(timeout = 2000)
public void promiseDoesNotInfiniteLoop() throws InterruptedException { public void promiseDoesNotInfiniteLoop() throws InterruptedException {
EmbeddedChannel channel = new EmbeddedChannel(); EmbeddedChannel channel = new EmbeddedChannel();
channel.closeFuture().addListener(new ChannelFutureListener() { channel.closeFuture().addListener((ChannelFutureListener) future -> future.channel().close());
@Override
public void operationComplete(ChannelFuture future) throws Exception {
future.channel().close();
}
});
channel.close().syncUninterruptibly(); channel.close().syncUninterruptibly();
} }
@ -121,18 +117,8 @@ public class EmbeddedChannelTest {
public void testScheduling() throws Exception { public void testScheduling() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new ChannelInboundHandlerAdapter()); EmbeddedChannel ch = new EmbeddedChannel(new ChannelInboundHandlerAdapter());
final CountDownLatch latch = new CountDownLatch(2); final CountDownLatch latch = new CountDownLatch(2);
ScheduledFuture future = ch.eventLoop().schedule(new Runnable() { ScheduledFuture future = ch.eventLoop().schedule(latch::countDown, 1, TimeUnit.SECONDS);
@Override future.addListener((FutureListener) future1 -> latch.countDown());
public void run() {
latch.countDown();
}
}, 1, TimeUnit.SECONDS);
future.addListener(new FutureListener() {
@Override
public void operationComplete(Future future) throws Exception {
latch.countDown();
}
});
long next = ch.runScheduledPendingTasks(); long next = ch.runScheduledPendingTasks();
assertTrue(next > 0); assertTrue(next > 0);
// Sleep for the nanoseconds but also give extra 50ms as the clock my not be very precise and so fail the test // Sleep for the nanoseconds but also give extra 50ms as the clock my not be very precise and so fail the test
@ -145,10 +131,7 @@ public class EmbeddedChannelTest {
@Test @Test
public void testScheduledCancelled() throws Exception { public void testScheduledCancelled() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new ChannelInboundHandlerAdapter()); EmbeddedChannel ch = new EmbeddedChannel(new ChannelInboundHandlerAdapter());
ScheduledFuture<?> future = ch.eventLoop().schedule(new Runnable() { ScheduledFuture<?> future = ch.eventLoop().schedule(() -> { }, 1, TimeUnit.DAYS);
@Override
public void run() { }
}, 1, TimeUnit.DAYS);
ch.finish(); ch.finish();
assertTrue(future.isCancelled()); assertTrue(future.isCancelled());
} }
@ -200,35 +183,15 @@ public class EmbeddedChannelTest {
// See https://github.com/netty/netty/issues/4316. // See https://github.com/netty/netty/issues/4316.
@Test(timeout = 2000) @Test(timeout = 2000)
public void testFireChannelInactiveAndUnregisteredOnClose() throws InterruptedException { public void testFireChannelInactiveAndUnregisteredOnClose() throws InterruptedException {
testFireChannelInactiveAndUnregistered(new Action() { testFireChannelInactiveAndUnregistered(ChannelOutboundInvoker::close);
@Override testFireChannelInactiveAndUnregistered(channel -> channel.close(channel.newPromise()));
public ChannelFuture doRun(Channel channel) {
return channel.close();
}
});
testFireChannelInactiveAndUnregistered(new Action() {
@Override
public ChannelFuture doRun(Channel channel) {
return channel.close(channel.newPromise());
}
});
} }
@Test(timeout = 2000) @Test(timeout = 2000)
public void testFireChannelInactiveAndUnregisteredOnDisconnect() throws InterruptedException { public void testFireChannelInactiveAndUnregisteredOnDisconnect() throws InterruptedException {
testFireChannelInactiveAndUnregistered(new Action() { testFireChannelInactiveAndUnregistered(ChannelOutboundInvoker::disconnect);
@Override
public ChannelFuture doRun(Channel channel) {
return channel.disconnect();
}
});
testFireChannelInactiveAndUnregistered(new Action() { testFireChannelInactiveAndUnregistered(channel -> channel.disconnect(channel.newPromise()));
@Override
public ChannelFuture doRun(Channel channel) {
return channel.disconnect(channel.newPromise());
}
});
} }
private static void testFireChannelInactiveAndUnregistered(Action action) throws InterruptedException { private static void testFireChannelInactiveAndUnregistered(Action action) throws InterruptedException {
@ -237,13 +200,8 @@ public class EmbeddedChannelTest {
@Override @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { public void channelInactive(ChannelHandlerContext ctx) throws Exception {
latch.countDown(); latch.countDown();
ctx.executor().execute(new Runnable() { // Should be executed.
@Override ctx.executor().execute(latch::countDown);
public void run() {
// Should be executed.
latch.countDown();
}
});
} }
@Override @Override
@ -368,12 +326,7 @@ public class EmbeddedChannelTest {
@Override @Override
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise)
throws Exception { throws Exception {
ctx.executor().execute(new Runnable() { ctx.executor().execute(() -> ctx.write(msg, promise));
@Override
public void run() {
ctx.write(msg, promise);
}
});
} }
}); });
Object msg = new Object(); Object msg = new Object();
@ -391,11 +344,8 @@ public class EmbeddedChannelTest {
@Override @Override
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise)
throws Exception { throws Exception {
ctx.executor().schedule(new Runnable() { ctx.executor().schedule(() -> {
@Override ctx.writeAndFlush(msg, promise);
public void run() {
ctx.writeAndFlush(msg, promise);
}
}, delay, TimeUnit.MILLISECONDS); }, delay, TimeUnit.MILLISECONDS);
} }
}); });

View File

@ -117,13 +117,10 @@ public class LocalChannelTest {
// Connect to the server // Connect to the server
cc = cb.connect(sc.localAddress()).sync().channel(); cc = cb.connect(sc.localAddress()).sync().channel();
final Channel ccCpy = cc; final Channel ccCpy = cc;
cc.eventLoop().execute(new Runnable() { cc.eventLoop().execute(() -> {
@Override // Send a message event up the pipeline.
public void run() { ccCpy.pipeline().fireChannelRead("Hello, World");
// Send a message event up the pipeline. latch.countDown();
ccCpy.pipeline().fireChannelRead("Hello, World");
latch.countDown();
}
}); });
assertTrue(latch.await(5, SECONDS)); assertTrue(latch.await(5, SECONDS));
@ -370,18 +367,10 @@ public class LocalChannelTest {
final Channel ccCpy = cc; final Channel ccCpy = cc;
// Make sure a write operation is executed in the eventloop // Make sure a write operation is executed in the eventloop
cc.pipeline().lastContext().executor().execute(new Runnable() { cc.pipeline().lastContext().executor().execute(() -> {
@Override ChannelPromise promise = ccCpy.newPromise();
public void run() { promise.addListener((ChannelFutureListener) future -> ccCpy.pipeline().lastContext().close());
ChannelPromise promise = ccCpy.newPromise(); ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
ccCpy.pipeline().lastContext().close();
}
});
ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
}
}); });
assertTrue(messageLatch.await(5, SECONDS)); assertTrue(messageLatch.await(5, SECONDS));
@ -501,18 +490,11 @@ public class LocalChannelTest {
final Channel ccCpy = cc; final Channel ccCpy = cc;
// Make sure a write operation is executed in the eventloop // Make sure a write operation is executed in the eventloop
cc.pipeline().lastContext().executor().execute(new Runnable() { cc.pipeline().lastContext().executor().execute(() -> {
@Override ChannelPromise promise = ccCpy.newPromise();
public void run() { promise.addListener((ChannelFutureListener) future ->
ChannelPromise promise = ccCpy.newPromise(); ccCpy.writeAndFlush(data2.retainedDuplicate(), ccCpy.newPromise()));
promise.addListener(new ChannelFutureListener() { ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
@Override
public void operationComplete(ChannelFuture future) throws Exception {
ccCpy.writeAndFlush(data2.retainedDuplicate(), ccCpy.newPromise());
}
});
ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
}
}); });
assertTrue(messageLatch.await(5, SECONDS)); assertTrue(messageLatch.await(5, SECONDS));
@ -583,19 +565,13 @@ public class LocalChannelTest {
final Channel ccCpy = cc; final Channel ccCpy = cc;
// Make sure a write operation is executed in the eventloop // Make sure a write operation is executed in the eventloop
cc.pipeline().lastContext().executor().execute(new Runnable() { cc.pipeline().lastContext().executor().execute(() -> {
@Override ChannelPromise promise = ccCpy.newPromise();
public void run() { promise.addListener((ChannelFutureListener) future -> {
ChannelPromise promise = ccCpy.newPromise(); Channel serverChannelCpy = serverChannelRef.get();
promise.addListener(new ChannelFutureListener() { serverChannelCpy.writeAndFlush(data2.retainedDuplicate(), serverChannelCpy.newPromise());
@Override });
public void operationComplete(ChannelFuture future) throws Exception { ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
Channel serverChannelCpy = serverChannelRef.get();
serverChannelCpy.writeAndFlush(data2.retainedDuplicate(), serverChannelCpy.newPromise());
}
});
ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
}
}); });
assertTrue(messageLatch.await(5, SECONDS)); assertTrue(messageLatch.await(5, SECONDS));
@ -665,20 +641,14 @@ public class LocalChannelTest {
final Channel ccCpy = cc; final Channel ccCpy = cc;
// Make sure a write operation is executed in the eventloop // Make sure a write operation is executed in the eventloop
cc.pipeline().lastContext().executor().execute(new Runnable() { cc.pipeline().lastContext().executor().execute(() -> {
@Override ChannelPromise promise = ccCpy.newPromise();
public void run() { promise.addListener((ChannelFutureListener) future -> {
ChannelPromise promise = ccCpy.newPromise(); Channel serverChannelCpy = serverChannelRef.get();
promise.addListener(new ChannelFutureListener() { serverChannelCpy.writeAndFlush(
@Override data2.retainedDuplicate(), serverChannelCpy.newPromise());
public void operationComplete(ChannelFuture future) throws Exception { });
Channel serverChannelCpy = serverChannelRef.get(); ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
serverChannelCpy.writeAndFlush(
data2.retainedDuplicate(), serverChannelCpy.newPromise());
}
});
ccCpy.writeAndFlush(data.retainedDuplicate(), promise);
}
}); });
assertTrue(messageLatch.await(5, SECONDS)); assertTrue(messageLatch.await(5, SECONDS));
@ -747,47 +717,34 @@ public class LocalChannelTest {
ccCpy.closeFuture().addListener(clientChannelCloseLatch); ccCpy.closeFuture().addListener(clientChannelCloseLatch);
// Make sure a write operation is executed in the eventloop // Make sure a write operation is executed in the eventloop
cc.pipeline().lastContext().executor().execute(new Runnable() { cc.pipeline().lastContext().executor().execute(() ->
@Override
public void run() {
ccCpy.writeAndFlush(data.retainedDuplicate(), ccCpy.newPromise()) ccCpy.writeAndFlush(data.retainedDuplicate(), ccCpy.newPromise())
.addListener(new ChannelFutureListener() { .addListener((ChannelFutureListener) future -> {
@Override serverChannelCpy.eventLoop().execute(() -> {
public void operationComplete(ChannelFuture future) throws Exception { // The point of this test is to write while the peer is closed, so we should
serverChannelCpy.eventLoop().execute(new Runnable() { // ensure the peer is actually closed before we write.
@Override int waitCount = 0;
public void run() { while (ccCpy.isOpen()) {
// The point of this test is to write while the peer is closed, so we should try {
// ensure the peer is actually closed before we write. Thread.sleep(50);
int waitCount = 0; } catch (InterruptedException ignored) {
while (ccCpy.isOpen()) { // ignored
try {
Thread.sleep(50);
} catch (InterruptedException ignored) {
// ignored
}
if (++waitCount > 5) {
fail();
}
}
serverChannelCpy.writeAndFlush(data2.retainedDuplicate(),
serverChannelCpy.newPromise())
.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess() &&
future.cause() instanceof ClosedChannelException) {
writeFailLatch.countDown();
}
}
});
}
});
ccCpy.close();
} }
}); if (++waitCount > 5) {
} fail();
}); }
}
serverChannelCpy.writeAndFlush(data2.retainedDuplicate(),
serverChannelCpy.newPromise())
.addListener((ChannelFutureListener) future1 -> {
if (!future1.isSuccess() &&
future1.cause() instanceof ClosedChannelException) {
writeFailLatch.countDown();
}
});
});
ccCpy.close();
}));
assertTrue(serverMessageLatch.await(5, SECONDS)); assertTrue(serverMessageLatch.await(5, SECONDS));
assertTrue(writeFailLatch.await(5, SECONDS)); assertTrue(writeFailLatch.await(5, SECONDS));
@ -952,12 +909,9 @@ public class LocalChannelTest {
} }
private static void writeAndFlushReadOnSuccess(final ChannelHandlerContext ctx, Object msg) { private static void writeAndFlushReadOnSuccess(final ChannelHandlerContext ctx, Object msg) {
ctx.writeAndFlush(msg).addListener(new ChannelFutureListener() { ctx.writeAndFlush(msg).addListener((ChannelFutureListener) future -> {
@Override if (future.isSuccess()) {
public void operationComplete(ChannelFuture future) { ctx.read();
if (future.isSuccess()) {
ctx.read();
}
} }
}); });
} }
@ -1182,12 +1136,9 @@ public class LocalChannelTest {
if (!autoRead) { if (!autoRead) {
// The read will be scheduled 100ms in the future to ensure we not receive any // The read will be scheduled 100ms in the future to ensure we not receive any
// channelRead calls in the meantime. // channelRead calls in the meantime.
ctx.executor().schedule(new Runnable() { ctx.executor().schedule(() -> {
@Override read = 0;
public void run() { ctx.read();
read = 0;
ctx.read();
}
}, 100, TimeUnit.MILLISECONDS); }, 100, TimeUnit.MILLISECONDS);
} else { } else {
read = 0; read = 0;

View File

@ -266,12 +266,9 @@ public class LocalTransportThreadModelTest {
final int end = i + ELEMS_PER_ROUNDS; final int end = i + ELEMS_PER_ROUNDS;
i = end; i = end;
ch.eventLoop().execute(new Runnable() { ch.eventLoop().execute(() -> {
@Override for (int j = start; j < end; j ++) {
public void run() { ch.pipeline().fireChannelRead(Integer.valueOf(j));
for (int j = start; j < end; j ++) {
ch.pipeline().fireChannelRead(Integer.valueOf(j));
}
} }
}); });
} }
@ -304,14 +301,11 @@ public class LocalTransportThreadModelTest {
final int end = i + ELEMS_PER_ROUNDS; final int end = i + ELEMS_PER_ROUNDS;
i = end; i = end;
ch.pipeline().context(h6).executor().execute(new Runnable() { ch.pipeline().context(h6).executor().execute(() -> {
@Override for (int j = start; j < end; j ++) {
public void run() { ch.write(Integer.valueOf(j));
for (int j = start; j < end; j ++) {
ch.write(Integer.valueOf(j));
}
ch.flush();
} }
ch.flush();
}); });
} }

View File

@ -83,12 +83,7 @@ public class LocalTransportThreadModelTest2 {
return; return;
} }
localChannel.eventLoop().execute(new Runnable() { localChannel.eventLoop().execute(() -> close(localChannel, localRegistrationHandler));
@Override
public void run() {
close(localChannel, localRegistrationHandler);
}
});
// Wait until the connection is closed or the connection attempt fails. // Wait until the connection is closed or the connection attempt fails.
localChannel.closeFuture().awaitUninterruptibly(); localChannel.closeFuture().awaitUninterruptibly();

View File

@ -152,25 +152,22 @@ public class LocalTransportThreadModelTest3 {
Throwable cause = new Throwable(); Throwable cause = new Throwable();
Thread pipelineModifier = new Thread(new Runnable() { Thread pipelineModifier = new Thread(() -> {
@Override Random random = new Random();
public void run() {
Random random = new Random();
while (true) { while (true) {
try { try {
Thread.sleep(100); Thread.sleep(100);
} catch (InterruptedException e) { } catch (InterruptedException e) {
return; return;
}
if (!ch.isRegistered()) {
continue;
}
//EventForwardHandler forwardHandler = forwarders[random.nextInt(forwarders.length)];
ChannelHandler handler = ch.pipeline().removeFirst();
ch.pipeline().addBefore(groups[random.nextInt(groups.length)].next(), "recorder",
UUID.randomUUID().toString(), handler);
} }
if (!ch.isRegistered()) {
continue;
}
//EventForwardHandler forwardHandler = forwarders[random.nextInt(forwarders.length)];
ChannelHandler handler = ch.pipeline().removeFirst();
ch.pipeline().addBefore(groups[random.nextInt(groups.length)].next(), "recorder",
UUID.randomUUID().toString(), handler);
} }
}); });
pipelineModifier.setDaemon(true); pipelineModifier.setDaemon(true);

View File

@ -23,7 +23,6 @@ import io.netty.channel.MultithreadEventLoopGroup;
import io.netty.channel.SelectStrategy; import io.netty.channel.SelectStrategy;
import io.netty.channel.SelectStrategyFactory; import io.netty.channel.SelectStrategyFactory;
import io.netty.channel.SingleThreadEventLoop; import io.netty.channel.SingleThreadEventLoop;
import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.IntSupplier; import io.netty.util.IntSupplier;
@ -38,7 +37,6 @@ import java.nio.channels.SelectionKey;
import java.nio.channels.Selector; import java.nio.channels.Selector;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider; import java.nio.channels.spi.SelectorProvider;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -66,35 +64,15 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
Channel channel = new NioServerSocketChannel(loop, loop); Channel channel = new NioServerSocketChannel(loop, loop);
channel.register().syncUninterruptibly(); channel.register().syncUninterruptibly();
Selector selector = loop.submit(new Callable<Selector>() { Selector selector = loop.submit(nioHandler::unwrappedSelector).syncUninterruptibly().getNow();
@Override
public Selector call() throws Exception {
return nioHandler.unwrappedSelector();
}
}).syncUninterruptibly().getNow();
assertSame(selector, loop.submit(new Callable<Selector>() { assertSame(selector, loop.submit(nioHandler::unwrappedSelector).syncUninterruptibly().getNow());
@Override
public Selector call() throws Exception {
return nioHandler.unwrappedSelector();
}
}).syncUninterruptibly().getNow());
assertTrue(selector.isOpen()); assertTrue(selector.isOpen());
// Submit to the EventLoop so we are sure its really executed in a non-async manner. // Submit to the EventLoop so we are sure its really executed in a non-async manner.
loop.submit(new Runnable() { loop.submit(nioHandler::rebuildSelector).syncUninterruptibly();
@Override
public void run() {
nioHandler.rebuildSelector();
}
}).syncUninterruptibly();
Selector newSelector = loop.submit(new Callable<Selector>() { Selector newSelector = loop.submit(nioHandler::unwrappedSelector).syncUninterruptibly().getNow();
@Override
public Selector call() throws Exception {
return nioHandler.unwrappedSelector();
}
}).syncUninterruptibly().getNow();
assertTrue(newSelector.isOpen()); assertTrue(newSelector.isOpen());
assertNotSame(selector, newSelector); assertNotSame(selector, newSelector);
assertFalse(selector.isOpen()); assertFalse(selector.isOpen());
@ -110,11 +88,8 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
EventLoopGroup group = new MultithreadEventLoopGroup(1, NioHandler.newFactory()); EventLoopGroup group = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
final EventLoop el = group.next(); final EventLoop el = group.next();
Future<?> future = el.schedule(new Runnable() { Future<?> future = el.schedule(() -> {
@Override // NOOP
public void run() {
// NOOP
}
}, Long.MAX_VALUE, TimeUnit.MILLISECONDS); }, Long.MAX_VALUE, TimeUnit.MILLISECONDS);
assertFalse(future.awaitUninterruptibly(1000)); assertFalse(future.awaitUninterruptibly(1000));
@ -127,48 +102,25 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
final NioHandler nioHandler = (NioHandler) NioHandler.newFactory().newHandler(); final NioHandler nioHandler = (NioHandler) NioHandler.newFactory().newHandler();
EventLoop loop = new SingleThreadEventLoop(new DefaultThreadFactory("ioPool"), nioHandler); EventLoop loop = new SingleThreadEventLoop(new DefaultThreadFactory("ioPool"), nioHandler);
try { try {
Selector selector = loop.submit(new Callable<Selector>() { Selector selector = loop.submit(nioHandler::unwrappedSelector).syncUninterruptibly().getNow();
@Override
public Selector call() throws Exception {
return nioHandler.unwrappedSelector();
}
}).syncUninterruptibly().getNow();
assertTrue(selector.isOpen()); assertTrue(selector.isOpen());
loop.submit(new Runnable() { loop.submit(() -> {
@Override // Interrupt the thread which should not end-up in a busy spin and
public void run() { // so the selector should not have been rebuild.
// Interrupt the thread which should not end-up in a busy spin and Thread.currentThread().interrupt();
// so the selector should not have been rebuild.
Thread.currentThread().interrupt();
}
}).syncUninterruptibly(); }).syncUninterruptibly();
assertTrue(selector.isOpen()); assertTrue(selector.isOpen());
final CountDownLatch latch = new CountDownLatch(2); final CountDownLatch latch = new CountDownLatch(2);
loop.submit(new Runnable() { loop.submit(latch::countDown).syncUninterruptibly();
@Override
public void run() {
latch.countDown();
}
}).syncUninterruptibly();
loop.schedule(new Runnable() { loop.schedule(latch::countDown, 2, TimeUnit.SECONDS).syncUninterruptibly();
@Override
public void run() {
latch.countDown();
}
}, 2, TimeUnit.SECONDS).syncUninterruptibly();
latch.await(); latch.await();
assertSame(selector, loop.submit(new Callable<Selector>() { assertSame(selector, loop.submit(nioHandler::unwrappedSelector).syncUninterruptibly().getNow());
@Override
public Selector call() throws Exception {
return nioHandler.unwrappedSelector();
}
}).syncUninterruptibly().getNow());
assertTrue(selector.isOpen()); assertTrue(selector.isOpen());
} finally { } finally {
loop.shutdownGracefully(); loop.shutdownGracefully();
@ -190,9 +142,7 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
loop.execute(new Runnable() { loop.execute(() ->
@Override
public void run() {
nioHandler.register(selectableChannel, SelectionKey.OP_CONNECT, new NioTask<SocketChannel>() { nioHandler.register(selectableChannel, SelectionKey.OP_CONNECT, new NioTask<SocketChannel>() {
@Override @Override
public void channelReady(SocketChannel ch, SelectionKey key) { public void channelReady(SocketChannel ch, SelectionKey key) {
@ -202,9 +152,7 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
@Override @Override
public void channelUnregistered(SocketChannel ch, Throwable cause) { public void channelUnregistered(SocketChannel ch, Throwable cause) {
} }
}); }));
}
});
latch.await(); latch.await();
@ -219,27 +167,21 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
@Test @Test
public void testTaskRemovalOnShutdownThrowsNoUnsupportedOperationException() throws Exception { public void testTaskRemovalOnShutdownThrowsNoUnsupportedOperationException() throws Exception {
final AtomicReference<Throwable> error = new AtomicReference<>(); final AtomicReference<Throwable> error = new AtomicReference<>();
final Runnable task = new Runnable() { final Runnable task = () -> {
@Override // NOOP
public void run() {
// NOOP
}
}; };
// Just run often enough to trigger it normally. // Just run often enough to trigger it normally.
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
EventLoopGroup group = new MultithreadEventLoopGroup(1, NioHandler.newFactory()); EventLoopGroup group = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
final EventLoop loop = group.next(); final EventLoop loop = group.next();
Thread t = new Thread(new Runnable() { Thread t = new Thread(() -> {
@Override try {
public void run() { for (;;) {
try { loop.execute(task);
for (;;) {
loop.execute(task);
}
} catch (Throwable cause) {
error.set(cause);
} }
} catch (Throwable cause) {
error.set(cause);
} }
}); });
t.start(); t.start();
@ -255,24 +197,19 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
public void testRebuildSelectorOnIOException() throws InterruptedException { public void testRebuildSelectorOnIOException() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
final CountDownLatch strategyLatch = new CountDownLatch(1); final CountDownLatch strategyLatch = new CountDownLatch(1);
SelectStrategyFactory selectStrategyFactory = new SelectStrategyFactory() { SelectStrategyFactory selectStrategyFactory = () -> new SelectStrategy() {
private boolean thrown;
@Override @Override
public SelectStrategy newSelectStrategy() { public int calculateStrategy(IntSupplier selectSupplier, boolean hasTasks) throws Exception {
return new SelectStrategy() { strategyLatch.await();
if (!thrown) {
private boolean thrown; thrown = true;
throw new IOException();
@Override }
public int calculateStrategy(IntSupplier selectSupplier, boolean hasTasks) throws Exception { latch.countDown();
strategyLatch.await(); return -1;
if (!thrown) {
thrown = true;
throw new IOException();
}
latch.countDown();
return -1;
}
};
} }
}; };
@ -289,12 +226,7 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
latch.await(); latch.await();
Selector newSelector = loop.submit(new Callable<Selector>() { Selector newSelector = loop.submit(nioHandler::unwrappedSelector).syncUninterruptibly().getNow();
@Override
public Selector call() throws Exception {
return nioHandler.unwrappedSelector();
}
}).syncUninterruptibly().getNow();
assertTrue(newSelector.isOpen()); assertTrue(newSelector.isOpen());
assertNotSame(selector, newSelector); assertNotSame(selector, newSelector);
assertFalse(selector.isOpen()); assertFalse(selector.isOpen());

View File

@ -132,12 +132,9 @@ public class NioSocketChannelTest extends AbstractNioChannelTest<NioSocketChanne
// Trigger a gathering write by writing two buffers. // Trigger a gathering write by writing two buffers.
ctx.write(Unpooled.wrappedBuffer(new byte[] { 'a' })); ctx.write(Unpooled.wrappedBuffer(new byte[] { 'a' }));
ChannelFuture f = ctx.write(Unpooled.wrappedBuffer(new byte[] { 'b' })); ChannelFuture f = ctx.write(Unpooled.wrappedBuffer(new byte[] { 'b' }));
f.addListener(new ChannelFutureListener() { f.addListener((ChannelFutureListener) future -> {
@Override // This message must be flushed
public void operationComplete(ChannelFuture future) throws Exception { ctx.writeAndFlush(Unpooled.wrappedBuffer(new byte[]{'c'}));
// This message must be flushed
ctx.writeAndFlush(Unpooled.wrappedBuffer(new byte[]{'c'}));
}
}); });
ctx.flush(); ctx.flush();
} }
@ -197,12 +194,9 @@ public class NioSocketChannelTest extends AbstractNioChannelTest<NioSocketChanne
// As soon as the channel becomes active re-register it to another // As soon as the channel becomes active re-register it to another
// EventLoop. After this is done we should still receive the data that // EventLoop. After this is done we should still receive the data that
// was written to the channel. // was written to the channel.
ctx.deregister().addListener(new ChannelFutureListener() { ctx.deregister().addListener((ChannelFutureListener) cf -> {
@Override Channel channel = cf.channel();
public void operationComplete(ChannelFuture cf) { channel.register();
Channel channel = cf.channel();
channel.register();
}
}); });
} }
}); });