Re-add Unsafe.voidPromise() which can be used for Unsafe operations for which no notification should be done [#1375]
This commit is contained in:
parent
d9c700e9fe
commit
f7931af704
|
@ -79,7 +79,8 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||||
private final Unsafe unsafe;
|
private final Unsafe unsafe;
|
||||||
private final DefaultChannelPipeline pipeline;
|
private final DefaultChannelPipeline pipeline;
|
||||||
private final ChannelFuture succeededFuture = new SucceededChannelFuture(this, null);
|
private final ChannelFuture succeededFuture = new SucceededChannelFuture(this, null);
|
||||||
private final VoidChannelPromise voidPromise = new VoidChannelPromise(this);
|
private final VoidChannelPromise voidPromise = new VoidChannelPromise(this, true);
|
||||||
|
private final VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false);
|
||||||
private final CloseFuture closeFuture = new CloseFuture(this);
|
private final CloseFuture closeFuture = new CloseFuture(this);
|
||||||
|
|
||||||
protected final ChannelFlushPromiseNotifier flushFutureNotifier = new ChannelFlushPromiseNotifier();
|
protected final ChannelFlushPromiseNotifier flushFutureNotifier = new ChannelFlushPromiseNotifier();
|
||||||
|
@ -936,6 +937,11 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelPromise voidPromise() {
|
||||||
|
return unsafeVoidPromise;
|
||||||
|
}
|
||||||
|
|
||||||
protected final boolean ensureOpen(ChannelPromise promise) {
|
protected final boolean ensureOpen(ChannelPromise promise) {
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -177,6 +177,7 @@ public interface Channel extends AttributeMap, ChannelOutboundInvoker, ChannelPr
|
||||||
* <li>{@link #remoteAddress()}</li>
|
* <li>{@link #remoteAddress()}</li>
|
||||||
* <li>{@link #closeForcibly()}</li>
|
* <li>{@link #closeForcibly()}</li>
|
||||||
* <li>{@link #register(EventLoop, ChannelPromise)}</li>
|
* <li>{@link #register(EventLoop, ChannelPromise)}</li>
|
||||||
|
* <li>{@link #voidPromise()}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
interface Unsafe {
|
interface Unsafe {
|
||||||
|
@ -265,5 +266,12 @@ public interface Channel extends AttributeMap, ChannelOutboundInvoker, ChannelPr
|
||||||
* automaticly call {@link FileRegion#release()}.
|
* automaticly call {@link FileRegion#release()}.
|
||||||
*/
|
*/
|
||||||
void sendFile(FileRegion region, ChannelPromise promise);
|
void sendFile(FileRegion region, ChannelPromise promise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a special ChannelPromise which can be reused and passed to the operations in {@link Unsafe}.
|
||||||
|
* It will never be notified of a success or error and so is only a placeholder for operations
|
||||||
|
* that take a {@link ChannelPromise} as argument but for which you not want to get notified.
|
||||||
|
*/
|
||||||
|
ChannelPromise voidPromise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class ThreadPerChannelEventLoop extends SingleThreadEventLoop {
|
||||||
Channel ch = this.ch;
|
Channel ch = this.ch;
|
||||||
if (isShuttingDown()) {
|
if (isShuttingDown()) {
|
||||||
if (ch != null) {
|
if (ch != null) {
|
||||||
ch.unsafe().close(ch.voidPromise());
|
ch.unsafe().close(ch.unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
if (confirmShutdown()) {
|
if (confirmShutdown()) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -24,17 +24,19 @@ import java.util.concurrent.TimeUnit;
|
||||||
final class VoidChannelPromise extends AbstractFuture<Void> implements ChannelPromise {
|
final class VoidChannelPromise extends AbstractFuture<Void> implements ChannelPromise {
|
||||||
|
|
||||||
private final Channel channel;
|
private final Channel channel;
|
||||||
|
private final boolean fireException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
* @param channel the {@link Channel} associated with this future
|
* @param channel the {@link Channel} associated with this future
|
||||||
*/
|
*/
|
||||||
public VoidChannelPromise(Channel channel) {
|
public VoidChannelPromise(Channel channel, boolean fireException) {
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
throw new NullPointerException("channel");
|
throw new NullPointerException("channel");
|
||||||
}
|
}
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
|
this.fireException = fireException;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -132,7 +134,9 @@ final class VoidChannelPromise extends AbstractFuture<Void> implements ChannelPr
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public VoidChannelPromise setFailure(Throwable cause) {
|
public VoidChannelPromise setFailure(Throwable cause) {
|
||||||
channel.pipeline().fireExceptionCaught(cause);
|
if (fireException) {
|
||||||
|
channel.pipeline().fireExceptionCaught(cause);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +147,9 @@ final class VoidChannelPromise extends AbstractFuture<Void> implements ChannelPr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryFailure(Throwable cause) {
|
public boolean tryFailure(Throwable cause) {
|
||||||
channel.pipeline().fireExceptionCaught(cause);
|
if (fireException) {
|
||||||
|
channel.pipeline().fireExceptionCaught(cause);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ final class AioEventLoop extends SingleThreadEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Channel ch: channels) {
|
for (Channel ch: channels) {
|
||||||
ch.unsafe().close(ch.voidPromise());
|
ch.unsafe().close(ch.unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class LocalChannel extends AbstractChannel {
|
||||||
private final Runnable shutdownHook = new Runnable() {
|
private final Runnable shutdownHook = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
unsafe().close(voidPromise());
|
unsafe().close(unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ public class LocalChannel extends AbstractChannel {
|
||||||
protected void doClose() throws Exception {
|
protected void doClose() throws Exception {
|
||||||
LocalChannel peer = this.peer;
|
LocalChannel peer = this.peer;
|
||||||
if (peer != null && peer.isActive()) {
|
if (peer != null && peer.isActive()) {
|
||||||
peer.unsafe().close(voidPromise());
|
peer.unsafe().close(unsafe().voidPromise());
|
||||||
this.peer = null;
|
this.peer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ public class LocalChannel extends AbstractChannel {
|
||||||
@Override
|
@Override
|
||||||
protected Runnable doDeregister() throws Exception {
|
protected Runnable doDeregister() throws Exception {
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
unsafe().close(voidPromise());
|
unsafe().close(unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
((SingleThreadEventExecutor) eventLoop()).removeShutdownHook(shutdownHook);
|
((SingleThreadEventExecutor) eventLoop()).removeShutdownHook(shutdownHook);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class LocalServerChannel extends AbstractServerChannel {
|
||||||
private final Runnable shutdownHook = new Runnable() {
|
private final Runnable shutdownHook = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
unsafe().close(voidPromise());
|
unsafe().close(unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -243,7 +243,7 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
||||||
logger.warn("Failed to re-register a Channel to the new Selector.", e);
|
logger.warn("Failed to re-register a Channel to the new Selector.", e);
|
||||||
if (a instanceof AbstractNioChannel) {
|
if (a instanceof AbstractNioChannel) {
|
||||||
AbstractNioChannel ch = (AbstractNioChannel) a;
|
AbstractNioChannel ch = (AbstractNioChannel) a;
|
||||||
ch.unsafe().close(ch.voidPromise());
|
ch.unsafe().close(ch.unsafe().voidPromise());
|
||||||
} else {
|
} else {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
|
NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
|
||||||
|
@ -418,7 +418,7 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
||||||
final NioUnsafe unsafe = ch.unsafe();
|
final NioUnsafe unsafe = ch.unsafe();
|
||||||
if (!k.isValid()) {
|
if (!k.isValid()) {
|
||||||
// close the channel if the key is not valid anymore
|
// close the channel if the key is not valid anymore
|
||||||
unsafe.close(ch.voidPromise());
|
unsafe.close(unsafe.voidPromise());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
||||||
if (readyOps != -1 && (readyOps & SelectionKey.OP_WRITE) != 0) {
|
if (readyOps != -1 && (readyOps & SelectionKey.OP_WRITE) != 0) {
|
||||||
unregisterWritableTasks(ch);
|
unregisterWritableTasks(ch);
|
||||||
}
|
}
|
||||||
unsafe.close(ch.voidPromise());
|
unsafe.close(unsafe.voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +518,7 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
||||||
|
|
||||||
for (AbstractNioChannel ch: channels) {
|
for (AbstractNioChannel ch: channels) {
|
||||||
unregisterWritableTasks(ch);
|
unregisterWritableTasks(ch);
|
||||||
ch.unsafe().close(ch.voidPromise());
|
ch.unsafe().close(ch.unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||||
if (Boolean.TRUE.equals(config().getOption(ChannelOption.ALLOW_HALF_CLOSURE))) {
|
if (Boolean.TRUE.equals(config().getOption(ChannelOption.ALLOW_HALF_CLOSURE))) {
|
||||||
pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
|
pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
|
||||||
} else {
|
} else {
|
||||||
unsafe().close(voidPromise());
|
unsafe().close(unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!firedInboundBufferSuspeneded) {
|
} else if (!firedInboundBufferSuspeneded) {
|
||||||
|
|
|
@ -56,7 +56,7 @@ public abstract class AbstractOioMessageChannel extends AbstractOioChannel {
|
||||||
pipeline.fireChannelReadSuspended();
|
pipeline.fireChannelReadSuspended();
|
||||||
pipeline.fireExceptionCaught(t);
|
pipeline.fireExceptionCaught(t);
|
||||||
if (t instanceof IOException) {
|
if (t instanceof IOException) {
|
||||||
unsafe().close(voidPromise());
|
unsafe().close(unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (read) {
|
if (read) {
|
||||||
|
@ -66,7 +66,7 @@ public abstract class AbstractOioMessageChannel extends AbstractOioChannel {
|
||||||
pipeline.fireChannelReadSuspended();
|
pipeline.fireChannelReadSuspended();
|
||||||
}
|
}
|
||||||
if (closed && isOpen()) {
|
if (closed && isOpen()) {
|
||||||
unsafe().close(voidPromise());
|
unsafe().close(unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -432,7 +432,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
|
||||||
//
|
//
|
||||||
// See http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousSocketChannel.html
|
// See http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousSocketChannel.html
|
||||||
if (cause instanceof InterruptedByTimeoutException) {
|
if (cause instanceof InterruptedByTimeoutException) {
|
||||||
channel.unsafe().close(channel.voidPromise());
|
channel.unsafe().close(channel.unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -493,7 +493,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
|
||||||
if (channel.config().isAllowHalfClosure()) {
|
if (channel.config().isAllowHalfClosure()) {
|
||||||
pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
|
pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
|
||||||
} else {
|
} else {
|
||||||
channel.unsafe().close(channel.voidPromise());
|
channel.unsafe().close(channel.unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!firedChannelReadSuspended) {
|
} else if (!firedChannelReadSuspended) {
|
||||||
|
@ -517,7 +517,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
|
||||||
//
|
//
|
||||||
// See http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousSocketChannel.html
|
// See http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousSocketChannel.html
|
||||||
if (t instanceof IOException || t instanceof InterruptedByTimeoutException) {
|
if (t instanceof IOException || t instanceof InterruptedByTimeoutException) {
|
||||||
channel.unsafe().close(channel.voidPromise());
|
channel.unsafe().close(channel.unsafe().voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user