DefaultChannelPipeline.estimatorHandle needs to be volatile
Motivation: DefaultChannelPipeline.estimatorHandle needs to be volatile as its accessed from different threads. Modifications: Make DefaultChannelPipeline.estimatorHandle volatile and correctly init it via CAS Result: No more race.
This commit is contained in:
parent
fe8ecea366
commit
339131c660
@ -36,6 +36,7 @@ import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||
|
||||
/**
|
||||
* The default {@link ChannelPipeline} implementation. It is usually created
|
||||
@ -56,6 +57,9 @@ public class DefaultChannelPipeline implements ChannelPipeline {
|
||||
}
|
||||
};
|
||||
|
||||
private static final AtomicReferenceFieldUpdater<DefaultChannelPipeline, MessageSizeEstimator.Handle> ESTIMATOR =
|
||||
AtomicReferenceFieldUpdater.newUpdater(
|
||||
DefaultChannelPipeline.class, MessageSizeEstimator.Handle.class, "estimatorHandle");
|
||||
final AbstractChannelHandlerContext head;
|
||||
final AbstractChannelHandlerContext tail;
|
||||
|
||||
@ -65,7 +69,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
|
||||
private final boolean touch = ResourceLeakDetector.isEnabled();
|
||||
|
||||
private Map<EventExecutorGroup, EventExecutor> childExecutors;
|
||||
private MessageSizeEstimator.Handle estimatorHandle;
|
||||
private volatile MessageSizeEstimator.Handle estimatorHandle;
|
||||
private boolean firstRegistration = true;
|
||||
|
||||
/**
|
||||
@ -97,10 +101,14 @@ public class DefaultChannelPipeline implements ChannelPipeline {
|
||||
}
|
||||
|
||||
final MessageSizeEstimator.Handle estimatorHandle() {
|
||||
if (estimatorHandle == null) {
|
||||
estimatorHandle = channel.config().getMessageSizeEstimator().newHandle();
|
||||
MessageSizeEstimator.Handle handle = estimatorHandle;
|
||||
if (handle == null) {
|
||||
handle = channel.config().getMessageSizeEstimator().newHandle();
|
||||
if (!ESTIMATOR.compareAndSet(this, null, handle)) {
|
||||
handle = estimatorHandle;
|
||||
}
|
||||
}
|
||||
return estimatorHandle;
|
||||
return handle;
|
||||
}
|
||||
|
||||
final Object touch(Object msg, AbstractChannelHandlerContext next) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user