Added direct buffer support (disabled by default and can't be enabled without recompilation for now - should be fixed in 3.1.)
This commit is contained in:
parent
b64124efd6
commit
5170838e79
@ -32,6 +32,7 @@ import java.nio.channels.ScatteringByteChannel;
|
|||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
import java.nio.channels.Selector;
|
import java.nio.channels.Selector;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@ -65,6 +66,7 @@ class NioWorker implements Runnable {
|
|||||||
InternalLoggerFactory.getInstance(NioWorker.class);
|
InternalLoggerFactory.getInstance(NioWorker.class);
|
||||||
|
|
||||||
private static final int CONSTRAINT_LEVEL = NioProviderMetadata.CONSTRAINT_LEVEL;
|
private static final int CONSTRAINT_LEVEL = NioProviderMetadata.CONSTRAINT_LEVEL;
|
||||||
|
private static final boolean USE_DIRECT_BUFFER = false; // Hard-coded for now
|
||||||
|
|
||||||
private final int bossId;
|
private final int bossId;
|
||||||
private final int id;
|
private final int id;
|
||||||
@ -74,8 +76,7 @@ class NioWorker implements Runnable {
|
|||||||
volatile Selector selector;
|
volatile Selector selector;
|
||||||
final AtomicBoolean wakenUp = new AtomicBoolean();
|
final AtomicBoolean wakenUp = new AtomicBoolean();
|
||||||
final ReadWriteLock selectorGuard = new ReentrantReadWriteLock();
|
final ReadWriteLock selectorGuard = new ReentrantReadWriteLock();
|
||||||
final ConcurrentLinkedQueue<Runnable> taskQueue = new ConcurrentLinkedQueue<Runnable>();
|
final Queue<Runnable> taskQueue = new ConcurrentLinkedQueue<Runnable>();
|
||||||
//final ConcurrentFastQueue<Runnable> taskQueue = new ConcurrentFastQueue<Runnable>();
|
|
||||||
|
|
||||||
NioWorker(int bossId, int id, Executor executor) {
|
NioWorker(int bossId, int id, Executor executor) {
|
||||||
this.bossId = bossId;
|
this.bossId = bossId;
|
||||||
@ -254,7 +255,16 @@ class NioWorker implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (k.isReadable()) {
|
if (k.isReadable()) {
|
||||||
read(k);
|
|
||||||
|
// TODO Replace ReceiveBufferSizePredictor with
|
||||||
|
// ChannelBufferAllocator and let user specify it per
|
||||||
|
// Channel. (Netty 3.1)
|
||||||
|
|
||||||
|
if (USE_DIRECT_BUFFER) {
|
||||||
|
readIntoDirectBuffer(k);
|
||||||
|
} else {
|
||||||
|
readIntoHeapBuffer(k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!k.isValid()) {
|
if (!k.isValid()) {
|
||||||
@ -268,12 +278,13 @@ class NioWorker implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void read(SelectionKey k) {
|
private static void readIntoHeapBuffer(SelectionKey k) {
|
||||||
ScatteringByteChannel ch = (ScatteringByteChannel) k.channel();
|
ScatteringByteChannel ch = (ScatteringByteChannel) k.channel();
|
||||||
NioSocketChannel channel = (NioSocketChannel) k.attachment();
|
NioSocketChannel channel = (NioSocketChannel) k.attachment();
|
||||||
|
|
||||||
ReceiveBufferSizePredictor predictor =
|
ReceiveBufferSizePredictor predictor =
|
||||||
channel.getConfig().getReceiveBufferSizePredictor();
|
channel.getConfig().getReceiveBufferSizePredictor();
|
||||||
|
|
||||||
ChannelBuffer buf = ChannelBuffers.buffer(predictor.nextReceiveBufferSize());
|
ChannelBuffer buf = ChannelBuffers.buffer(predictor.nextReceiveBufferSize());
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -306,6 +317,62 @@ class NioWorker implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ChannelBuffer preallocatedDirectBuffer;
|
||||||
|
|
||||||
|
private static void readIntoDirectBuffer(SelectionKey k) {
|
||||||
|
ScatteringByteChannel ch = (ScatteringByteChannel) k.channel();
|
||||||
|
NioSocketChannel channel = (NioSocketChannel) k.attachment();
|
||||||
|
|
||||||
|
ReceiveBufferSizePredictor predictor =
|
||||||
|
channel.getConfig().getReceiveBufferSizePredictor();
|
||||||
|
|
||||||
|
ChannelBuffer preallocatedDirectBuffer = channel.getWorker().preallocatedDirectBuffer;
|
||||||
|
NioWorker worker = channel.getWorker();
|
||||||
|
worker.preallocatedDirectBuffer = null;
|
||||||
|
|
||||||
|
if (preallocatedDirectBuffer == null) {
|
||||||
|
preallocatedDirectBuffer = ChannelBuffers.directBuffer(1048576);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
int readBytes = 0;
|
||||||
|
boolean failure = true;
|
||||||
|
try {
|
||||||
|
while ((ret = preallocatedDirectBuffer.writeBytes(ch, preallocatedDirectBuffer.writableBytes())) > 0) {
|
||||||
|
readBytes += ret;
|
||||||
|
if (!preallocatedDirectBuffer.writable()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failure = false;
|
||||||
|
} catch (AsynchronousCloseException e) {
|
||||||
|
// Can happen, and doesn't need a user attention.
|
||||||
|
} catch (Throwable t) {
|
||||||
|
fireExceptionCaught(channel, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readBytes > 0) {
|
||||||
|
// Update the predictor.
|
||||||
|
predictor.previousReceiveBufferSize(readBytes);
|
||||||
|
|
||||||
|
// Fire the event.
|
||||||
|
ChannelBuffer slice = preallocatedDirectBuffer.slice(
|
||||||
|
preallocatedDirectBuffer.readerIndex(),
|
||||||
|
preallocatedDirectBuffer.readableBytes());
|
||||||
|
preallocatedDirectBuffer.readerIndex(preallocatedDirectBuffer.writerIndex());
|
||||||
|
if (preallocatedDirectBuffer.writable()) {
|
||||||
|
worker.preallocatedDirectBuffer = preallocatedDirectBuffer;
|
||||||
|
}
|
||||||
|
fireMessageReceived(channel, slice);
|
||||||
|
} else if (readBytes == 0) {
|
||||||
|
worker.preallocatedDirectBuffer = preallocatedDirectBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0 || failure) {
|
||||||
|
close(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void write(SelectionKey k) {
|
private static void write(SelectionKey k) {
|
||||||
NioSocketChannel ch = (NioSocketChannel) k.attachment();
|
NioSocketChannel ch = (NioSocketChannel) k.attachment();
|
||||||
write(ch, false);
|
write(ch, false);
|
||||||
|
Loading…
Reference in New Issue
Block a user