diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java index 6299bf6766..e2b3da728b 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java @@ -70,9 +70,9 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im ((AbstractEpollUnsafe) unsafe()).flush0(); } }; - private Queue spliceQueue; // Lazy init these if we need to splice(...) + private volatile Queue spliceQueue; private FileDescriptor pipeIn; private FileDescriptor pipeOut; @@ -678,13 +678,14 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im } private void clearSpliceQueue() { - if (spliceQueue == null) { + Queue sQueue = spliceQueue; + if (sQueue == null) { return; } ClosedChannelException exception = null; for (;;) { - SpliceInTask task = spliceQueue.poll(); + SpliceInTask task = sQueue.poll(); if (task == null) { break; } @@ -755,15 +756,16 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im ByteBuf byteBuf = null; boolean close = false; try { + Queue sQueue = null; do { - if (spliceQueue != null) { - SpliceInTask spliceTask = spliceQueue.peek(); + if (sQueue != null || (sQueue = spliceQueue) != null) { + SpliceInTask spliceTask = sQueue.peek(); if (spliceTask != null) { if (spliceTask.spliceIn(allocHandle)) { // We need to check if it is still active as if not we removed all SpliceTasks in // doClose(...) if (isActive()) { - spliceQueue.remove(); + sQueue.remove(); } continue; } else { @@ -823,24 +825,16 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im } private void addToSpliceQueue(final SpliceInTask task) { - EventLoop eventLoop = eventLoop(); - if (eventLoop.inEventLoop()) { - addToSpliceQueue0(task); - } else { - eventLoop.execute(new Runnable() { - @Override - public void run() { - addToSpliceQueue0(task); + Queue sQueue = spliceQueue; + if (sQueue == null) { + synchronized (this) { + sQueue = spliceQueue; + if (sQueue == null) { + spliceQueue = sQueue = PlatformDependent.newMpscQueue(); } - }); + } } - } - - private void addToSpliceQueue0(SpliceInTask task) { - if (spliceQueue == null) { - spliceQueue = PlatformDependent.newMpscQueue(); - } - spliceQueue.add(task); + sQueue.add(task); } protected abstract class SpliceInTask {