Define a dedicated exception for performing blocking ops in event loop
This commit is contained in:
parent
7be188f8c0
commit
d626561b59
@ -0,0 +1,26 @@
|
|||||||
|
package io.netty.channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link IllegalStateException} which is raised when a user performed a blocking operation
|
||||||
|
* when the user is in an event loop thread. If a blocking operation is performed in an event loop
|
||||||
|
* thread, the blocking operation will most likely enter a dead lock state, hence throwing this
|
||||||
|
* exception.
|
||||||
|
*/
|
||||||
|
public class BlockingOperationException extends IllegalStateException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2462223247762460301L;
|
||||||
|
|
||||||
|
public BlockingOperationException() {}
|
||||||
|
|
||||||
|
public BlockingOperationException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockingOperationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockingOperationException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,6 @@ import static java.util.concurrent.TimeUnit.*;
|
|||||||
import io.netty.channel.AbstractChannel.FlushCheckpoint;
|
import io.netty.channel.AbstractChannel.FlushCheckpoint;
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
import io.netty.logging.InternalLoggerFactory;
|
import io.netty.logging.InternalLoggerFactory;
|
||||||
import io.netty.util.internal.DeadLockProofWorker;
|
|
||||||
|
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -48,33 +47,6 @@ public class DefaultChannelFuture extends FlushCheckpoint implements ChannelFutu
|
|||||||
|
|
||||||
private static final Throwable CANCELLED = new Throwable();
|
private static final Throwable CANCELLED = new Throwable();
|
||||||
|
|
||||||
private static volatile boolean useDeadLockChecker = true;
|
|
||||||
private static boolean disabledDeadLockCheckerOnce;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} if and only if the dead lock checker is enabled.
|
|
||||||
*/
|
|
||||||
public static boolean isUseDeadLockChecker() {
|
|
||||||
return useDeadLockChecker;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables or disables the dead lock checker. It is not recommended to
|
|
||||||
* disable the dead lock checker. Disable it at your own risk!
|
|
||||||
*/
|
|
||||||
public static void setUseDeadLockChecker(boolean useDeadLockChecker) {
|
|
||||||
if (!useDeadLockChecker && !disabledDeadLockCheckerOnce) {
|
|
||||||
disabledDeadLockCheckerOnce = true;
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug(
|
|
||||||
"The dead lock checker in " +
|
|
||||||
DefaultChannelFuture.class.getSimpleName() +
|
|
||||||
" has been disabled as requested at your own risk.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DefaultChannelFuture.useDeadLockChecker = useDeadLockChecker;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Channel channel;
|
private final Channel channel;
|
||||||
private final boolean cancellable;
|
private final boolean cancellable;
|
||||||
|
|
||||||
@ -350,12 +322,9 @@ public class DefaultChannelFuture extends FlushCheckpoint implements ChannelFutu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkDeadLock() {
|
private void checkDeadLock() {
|
||||||
if (isUseDeadLockChecker() && DeadLockProofWorker.PARENT.get() != null) {
|
if (channel().eventLoop().inEventLoop()) {
|
||||||
throw new IllegalStateException(
|
throw new BlockingOperationException();
|
||||||
"await*() in I/O thread causes a dead lock or " +
|
|
||||||
"sudden performance drop. Use addListener() instead or " +
|
|
||||||
"call await*() from a different thread.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user