Added some javadocs and removed unsed code and excessive comments.
This commit is contained in:
parent
effbe32fdb
commit
c01e997a45
@ -49,16 +49,17 @@ import org.jboss.netty.util.internal.ThreadLocalBoolean;
|
|||||||
* NioDatagramChannel provides a connection less NIO UDP channel for Netty.
|
* NioDatagramChannel provides a connection less NIO UDP channel for Netty.
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
*
|
* @author Daniel Bevenius (dbevenius@jboss.com)
|
||||||
|
* @version $Rev$, $Date$
|
||||||
*/
|
*/
|
||||||
public class NioDatagramChannel extends AbstractChannel implements
|
public class NioDatagramChannel extends AbstractChannel implements
|
||||||
ServerChannel {
|
ServerChannel {
|
||||||
/**
|
/**
|
||||||
* Internal Netty logger.
|
* Internal Netty logger.
|
||||||
*/
|
*/
|
||||||
private static final InternalLogger logger =
|
private static final InternalLogger logger = InternalLoggerFactory
|
||||||
InternalLoggerFactory.getInstance(NioDatagramChannel.class);
|
.getInstance(NioDatagramChannel.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link DatagramChannelConfig}.
|
* The {@link DatagramChannelConfig}.
|
||||||
@ -76,22 +77,17 @@ public class NioDatagramChannel extends AbstractChannel implements
|
|||||||
private final DatagramChannel datagramChannel;
|
private final DatagramChannel datagramChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Monitor object to synchronize access to InterestedOps.
|
||||||
*/
|
|
||||||
volatile ChannelFuture connectFuture;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
final Object interestOpsLock = new Object();
|
final Object interestOpsLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Monitor object for synchronizing access to the {@link WriteBufferQueue}.
|
||||||
*/
|
*/
|
||||||
final Object writeLock = new Object();
|
final Object writeLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* WriteTask that performs write operations.
|
||||||
*/
|
*/
|
||||||
final Runnable writeTask = new WriteTask();
|
final Runnable writeTask = new WriteTask();
|
||||||
|
|
||||||
@ -101,7 +97,7 @@ public class NioDatagramChannel extends AbstractChannel implements
|
|||||||
final AtomicBoolean writeTaskInTaskQueue = new AtomicBoolean();
|
final AtomicBoolean writeTaskInTaskQueue = new AtomicBoolean();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Queue of write {@link MessageEvent}s.
|
||||||
*/
|
*/
|
||||||
final Queue<MessageEvent> writeBufferQueue = new WriteBufferQueue();
|
final Queue<MessageEvent> writeBufferQueue = new WriteBufferQueue();
|
||||||
|
|
||||||
@ -112,22 +108,22 @@ public class NioDatagramChannel extends AbstractChannel implements
|
|||||||
final AtomicInteger writeBufferSize = new AtomicInteger();
|
final AtomicInteger writeBufferSize = new AtomicInteger();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Keeps track of the highWaterMark.
|
||||||
*/
|
*/
|
||||||
final AtomicInteger highWaterMarkCounter = new AtomicInteger();
|
final AtomicInteger highWaterMarkCounter = new AtomicInteger();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* The current write {@link MessageEvent}
|
||||||
*/
|
*/
|
||||||
MessageEvent currentWriteEvent;
|
MessageEvent currentWriteEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* The current write index.
|
||||||
*/
|
*/
|
||||||
int currentWriteIndex;
|
int currentWriteIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Boolean that indicates that write operation is in progress.
|
||||||
*/
|
*/
|
||||||
volatile boolean inWriteNowLoop;
|
volatile boolean inWriteNowLoop;
|
||||||
|
|
||||||
@ -221,7 +217,6 @@ public class NioDatagramChannel extends AbstractChannel implements
|
|||||||
* WriteBuffer is an extension of {@link LinkedTransferQueue} that adds
|
* WriteBuffer is an extension of {@link LinkedTransferQueue} that adds
|
||||||
* support for highWaterMark checking of the write buffer size.
|
* support for highWaterMark checking of the write buffer size.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
|
|
||||||
*/
|
*/
|
||||||
private final class WriteBufferQueue extends
|
private final class WriteBufferQueue extends
|
||||||
LinkedTransferQueue<MessageEvent> {
|
LinkedTransferQueue<MessageEvent> {
|
||||||
@ -240,20 +235,15 @@ public class NioDatagramChannel extends AbstractChannel implements
|
|||||||
final boolean success = super.offer(e);
|
final boolean success = super.offer(e);
|
||||||
assert success;
|
assert success;
|
||||||
|
|
||||||
final int messageSize =
|
final int messageSize = ((ChannelBuffer) e.getMessage())
|
||||||
((ChannelBuffer) e.getMessage()).readableBytes();
|
.readableBytes();
|
||||||
|
|
||||||
// Add the ChannelBuffers size to the writeBuffersSize
|
final int newWriteBufferSize = writeBufferSize
|
||||||
final int newWriteBufferSize =
|
.addAndGet(messageSize);
|
||||||
writeBufferSize.addAndGet(messageSize);
|
|
||||||
|
|
||||||
final int highWaterMark = getConfig().getWriteBufferHighWaterMark();
|
final int highWaterMark = getConfig().getWriteBufferHighWaterMark();
|
||||||
// Check if the newly calculated buffersize exceeds the highWaterMark limit.
|
|
||||||
if (newWriteBufferSize >= highWaterMark) {
|
if (newWriteBufferSize >= highWaterMark) {
|
||||||
// Check to see if the messages size we are adding is what will cause the highWaterMark to be breached.
|
|
||||||
if (newWriteBufferSize - messageSize < highWaterMark) {
|
if (newWriteBufferSize - messageSize < highWaterMark) {
|
||||||
// Increment the highWaterMarkCounter which track of the fact that the count
|
|
||||||
// has been reached.
|
|
||||||
highWaterMarkCounter.incrementAndGet();
|
highWaterMarkCounter.incrementAndGet();
|
||||||
|
|
||||||
if (!notifying.get()) {
|
if (!notifying.get()) {
|
||||||
@ -275,16 +265,14 @@ public class NioDatagramChannel extends AbstractChannel implements
|
|||||||
public MessageEvent poll() {
|
public MessageEvent poll() {
|
||||||
final MessageEvent e = super.poll();
|
final MessageEvent e = super.poll();
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
final int messageSize =
|
final int messageSize = ((ChannelBuffer) e.getMessage())
|
||||||
((ChannelBuffer) e.getMessage()).readableBytes();
|
.readableBytes();
|
||||||
// Subtract the ChannelBuffers size from the writeBuffersSize
|
final int newWriteBufferSize = writeBufferSize
|
||||||
final int newWriteBufferSize =
|
.addAndGet(-messageSize);
|
||||||
writeBufferSize.addAndGet(-messageSize);
|
|
||||||
|
|
||||||
final int lowWaterMark =
|
final int lowWaterMark = getConfig()
|
||||||
getConfig().getWriteBufferLowWaterMark();
|
.getWriteBufferLowWaterMark();
|
||||||
|
|
||||||
// Check if the newly calculated buffersize exceeds the lowhWaterMark limit.
|
|
||||||
if (newWriteBufferSize == 0 ||
|
if (newWriteBufferSize == 0 ||
|
||||||
newWriteBufferSize < lowWaterMark) {
|
newWriteBufferSize < lowWaterMark) {
|
||||||
if (newWriteBufferSize + messageSize >= lowWaterMark) {
|
if (newWriteBufferSize + messageSize >= lowWaterMark) {
|
||||||
@ -304,8 +292,6 @@ public class NioDatagramChannel extends AbstractChannel implements
|
|||||||
/**
|
/**
|
||||||
* WriteTask is a simple runnable performs writes by delegating the {@link NioUdpWorker}.
|
* WriteTask is a simple runnable performs writes by delegating the {@link NioUdpWorker}.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private final class WriteTask implements Runnable {
|
private final class WriteTask implements Runnable {
|
||||||
WriteTask() {
|
WriteTask() {
|
||||||
|
@ -51,7 +51,9 @@ import org.jboss.netty.util.internal.ExecutorUtil;
|
|||||||
* threads. A worker thread performs non-blocking read and write for one or
|
* threads. A worker thread performs non-blocking read and write for one or
|
||||||
* more {@link Channel}s in a non-blocking mode.
|
* more {@link Channel}s in a non-blocking mode.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Daniel Bevenius (dbevenius@jboss.com)
|
||||||
|
* @version $Rev$, $Date$
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class NioDatagramChannelFactory implements ChannelFactory,
|
public class NioDatagramChannelFactory implements ChannelFactory,
|
||||||
|
@ -20,38 +20,33 @@
|
|||||||
*/
|
*/
|
||||||
package org.jboss.netty.channel.socket.nio;
|
package org.jboss.netty.channel.socket.nio;
|
||||||
|
|
||||||
import static org.jboss.netty.channel.Channels.*;
|
import static org.jboss.netty.channel.Channels.fireChannelBound;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireChannelClosed;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireChannelUnbound;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireExceptionCaught;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.jboss.netty.channel.AbstractChannelSink;
|
import org.jboss.netty.channel.AbstractChannelSink;
|
||||||
import org.jboss.netty.channel.ChannelEvent;
|
import org.jboss.netty.channel.ChannelEvent;
|
||||||
import org.jboss.netty.channel.ChannelFuture;
|
import org.jboss.netty.channel.ChannelFuture;
|
||||||
import org.jboss.netty.channel.ChannelFutureListener;
|
|
||||||
import org.jboss.netty.channel.ChannelPipeline;
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
import org.jboss.netty.channel.ChannelState;
|
import org.jboss.netty.channel.ChannelState;
|
||||||
import org.jboss.netty.channel.ChannelStateEvent;
|
import org.jboss.netty.channel.ChannelStateEvent;
|
||||||
import org.jboss.netty.channel.MessageEvent;
|
import org.jboss.netty.channel.MessageEvent;
|
||||||
import org.jboss.netty.logging.InternalLogger;
|
|
||||||
import org.jboss.netty.logging.InternalLoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NioDatagramPipelineSink receives downstream events from a ChannelPipeline.
|
* NioDatagramPipelineSink receives downstream events from a ChannelPipeline.
|
||||||
* <p/>
|
* <p/>
|
||||||
* A {@link NioDatagramPipelineSink} contains an array of {@link NioUdpWorker}s
|
* A {@link NioDatagramPipelineSink} contains an array of {@link NioUdpWorker}s
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Daniel Bevenius (dbevenius@jboss.com)
|
||||||
|
* @version $Rev$, $Date$
|
||||||
*/
|
*/
|
||||||
public class NioDatagramPipelineSink extends AbstractChannelSink {
|
public class NioDatagramPipelineSink extends AbstractChannelSink {
|
||||||
/**
|
|
||||||
* Internal Netty logger.
|
|
||||||
*/
|
|
||||||
private final InternalLogger logger =
|
|
||||||
InternalLoggerFactory.getInstance(NioDatagramPipelineSink.class);
|
|
||||||
|
|
||||||
private static final AtomicInteger nextId = new AtomicInteger();
|
private static final AtomicInteger nextId = new AtomicInteger();
|
||||||
|
|
||||||
@ -163,29 +158,4 @@ public class NioDatagramPipelineSink extends AbstractChannelSink {
|
|||||||
return workers[Math.abs(workerIndex.getAndIncrement() % workers.length)];
|
return workers[Math.abs(workerIndex.getAndIncrement() % workers.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The connection sematics of a NioDatagramPipelineSink are different for datagram sockets than they are for stream
|
|
||||||
* sockets. Placing a DatagramChannel into a connected state causes datagrams to be ignored from any source
|
|
||||||
* address other than the one to which the channel is connected. Unwanted packets will be dropped.
|
|
||||||
* Not sure that this makes sense for a server side component.
|
|
||||||
*
|
|
||||||
* @param channel The UdpChannel to connect from.
|
|
||||||
* @param future
|
|
||||||
* @param remoteAddress The remote address to connect to.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private void connect(final NioDatagramChannel channel,
|
|
||||||
ChannelFuture future, SocketAddress remoteAddress) {
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
channel.getDatagramChannel().socket().connect(remoteAddress);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
|
|
||||||
channel.connectFuture = future;
|
|
||||||
}
|
|
||||||
} catch (final Throwable t) {
|
|
||||||
future.setFailure(t);
|
|
||||||
fireExceptionCaught(channel, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.jboss.netty.channel.socket.nio;
|
package org.jboss.netty.channel.socket.nio;
|
||||||
|
|
||||||
import static org.jboss.netty.channel.Channels.*;
|
import static org.jboss.netty.channel.Channels.fireChannelClosed;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireChannelConnected;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireChannelDisconnected;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireChannelInterestChanged;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireChannelUnbound;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireExceptionCaught;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireMessageReceived;
|
||||||
|
import static org.jboss.netty.channel.Channels.fireWriteComplete;
|
||||||
|
import static org.jboss.netty.channel.Channels.succeededFuture;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
@ -55,25 +63,19 @@ import org.jboss.netty.util.ThreadRenamingRunnable;
|
|||||||
import org.jboss.netty.util.internal.LinkedTransferQueue;
|
import org.jboss.netty.util.internal.LinkedTransferQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* NioUdpWorker is responsible for registering channels with selector, and
|
||||||
|
* also manages the select process.
|
||||||
|
*
|
||||||
* @author The Netty Project (netty-dev@lists.jboss.org)
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
* @author Trustin Lee (tlee@redhat.com)
|
* @author Daniel Bevenius (dbevenius@jboss.com)
|
||||||
*
|
|
||||||
* @version $Rev$, $Date$
|
* @version $Rev$, $Date$
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class NioUdpWorker implements Runnable {
|
class NioUdpWorker implements Runnable {
|
||||||
/**
|
/**
|
||||||
* Internal Netty logger.
|
* Internal Netty logger.
|
||||||
*/
|
*/
|
||||||
private static final InternalLogger logger =
|
private static final InternalLogger logger = InternalLoggerFactory
|
||||||
InternalLoggerFactory.getInstance(NioUdpWorker.class);
|
.getInstance(NioUdpWorker.class);
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final int CONSTRAINT_LEVEL =
|
|
||||||
NioProviderMetadata.CONSTRAINT_LEVEL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum packate size for UDP packets.
|
* Maximum packate size for UDP packets.
|
||||||
@ -113,31 +115,39 @@ class NioUdpWorker implements Runnable {
|
|||||||
volatile Selector selector;
|
volatile Selector selector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Boolean that controls determines if a blocked Selector.select should
|
||||||
|
* break out of its selection process. In our case we use a timeone for
|
||||||
|
* the select method and the select method will block for that time unless
|
||||||
|
* woken up.
|
||||||
*/
|
*/
|
||||||
private final AtomicBoolean wakenUp = new AtomicBoolean();
|
private final AtomicBoolean wakenUp = new AtomicBoolean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock for this workers Selector.
|
||||||
|
*/
|
||||||
private final ReadWriteLock selectorGuard = new ReentrantReadWriteLock();
|
private final ReadWriteLock selectorGuard = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor object used to synchronize selector open/close.
|
||||||
|
*/
|
||||||
private final Object startStopLock = new Object();
|
private final Object startStopLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue of {@link ChannelRegistionTask}s
|
* Queue of {@link ChannelRegistionTask}s
|
||||||
*/
|
*/
|
||||||
private final Queue<Runnable> registerTaskQueue =
|
private final Queue<Runnable> registerTaskQueue = new LinkedTransferQueue<Runnable>();
|
||||||
new LinkedTransferQueue<Runnable>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue of
|
* Queue of WriteTasks
|
||||||
*/
|
*/
|
||||||
private final Queue<Runnable> writeTaskQueue =
|
private final Queue<Runnable> writeTaskQueue = new LinkedTransferQueue<Runnable>();
|
||||||
new LinkedTransferQueue<Runnable>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Sole constructor.
|
||||||
* @param bossId
|
*
|
||||||
* @param id
|
* @param bossId This id of the NioDatagramPipelineSink.
|
||||||
* @param executor
|
* @param id The id of this worker.
|
||||||
|
* @param executor Executor used to exeucte runnables such as {@link ChannelRegistionTask}.
|
||||||
*/
|
*/
|
||||||
NioUdpWorker(final int bossId, final int id, final Executor executor) {
|
NioUdpWorker(final int bossId, final int id, final Executor executor) {
|
||||||
this.bossId = bossId;
|
this.bossId = bossId;
|
||||||
@ -152,8 +162,8 @@ class NioUdpWorker implements Runnable {
|
|||||||
* @param future
|
* @param future
|
||||||
*/
|
*/
|
||||||
void register(final NioDatagramChannel channel, final ChannelFuture future) {
|
void register(final NioDatagramChannel channel, final ChannelFuture future) {
|
||||||
final Runnable channelRegTask =
|
final Runnable channelRegTask = new ChannelRegistionTask(channel,
|
||||||
new ChannelRegistionTask(channel, future);
|
future);
|
||||||
Selector selector;
|
Selector selector;
|
||||||
|
|
||||||
synchronized (startStopLock) {
|
synchronized (startStopLock) {
|
||||||
@ -168,6 +178,7 @@ class NioUdpWorker implements Runnable {
|
|||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
|
// Start the main selector loop. See run() for details.
|
||||||
executor.execute(new ThreadRenamingRunnable(this,
|
executor.execute(new ThreadRenamingRunnable(this,
|
||||||
"New I/O server worker #" + bossId + "'-'" + id));
|
"New I/O server worker #" + bossId + "'-'" + id));
|
||||||
success = true;
|
success = true;
|
||||||
@ -201,6 +212,9 @@ class NioUdpWorker implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector loop.
|
||||||
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
// Store a ref to the current thread.
|
// Store a ref to the current thread.
|
||||||
thread = Thread.currentThread();
|
thread = Thread.currentThread();
|
||||||
@ -211,7 +225,8 @@ class NioUdpWorker implements Runnable {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
wakenUp.set(false);
|
wakenUp.set(false);
|
||||||
|
|
||||||
if (CONSTRAINT_LEVEL != 0) {
|
//
|
||||||
|
if (NioProviderMetadata.CONSTRAINT_LEVEL != 0) {
|
||||||
selectorGuard.writeLock().lock();
|
selectorGuard.writeLock().lock();
|
||||||
// This empty synchronization block prevents the selector from acquiring its lock.
|
// This empty synchronization block prevents the selector from acquiring its lock.
|
||||||
selectorGuard.writeLock().unlock();
|
selectorGuard.writeLock().unlock();
|
||||||
@ -234,7 +249,8 @@ class NioUdpWorker implements Runnable {
|
|||||||
processSelectedKeys(selector.selectedKeys());
|
processSelectedKeys(selector.selectedKeys());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit the loop when there's nothing to handle.
|
// Exit the loop when there's nothing to handle (the registered
|
||||||
|
// key set is empty.
|
||||||
// The shutdown flag is used to delay the shutdown of this
|
// The shutdown flag is used to delay the shutdown of this
|
||||||
// loop to avoid excessive Selector creation when
|
// loop to avoid excessive Selector creation when
|
||||||
// connections are registered in a one-by-one manner instead of
|
// connections are registered in a one-by-one manner instead of
|
||||||
@ -338,8 +354,8 @@ class NioUdpWorker implements Runnable {
|
|||||||
* @param key The selection key which contains the Selector registration information.
|
* @param key The selection key which contains the Selector registration information.
|
||||||
*/
|
*/
|
||||||
private static void read(final SelectionKey key) {
|
private static void read(final SelectionKey key) {
|
||||||
final NioDatagramChannel nioDatagramChannel =
|
final NioDatagramChannel nioDatagramChannel = (NioDatagramChannel) key
|
||||||
(NioDatagramChannel) key.attachment();
|
.attachment();
|
||||||
|
|
||||||
final DatagramChannel datagramChannel = (DatagramChannel) key.channel();
|
final DatagramChannel datagramChannel = (DatagramChannel) key.channel();
|
||||||
try {
|
try {
|
||||||
@ -351,21 +367,14 @@ class NioUdpWorker implements Runnable {
|
|||||||
|
|
||||||
// Recieve from the channel in a non blocking mode. We have already been notified that
|
// Recieve from the channel in a non blocking mode. We have already been notified that
|
||||||
// the channel is ready to receive.
|
// the channel is ready to receive.
|
||||||
final SocketAddress remoteAddress =
|
final SocketAddress remoteAddress = datagramChannel
|
||||||
datagramChannel.receive(byteBuffer);
|
.receive(byteBuffer);
|
||||||
/*
|
|
||||||
if (remoteAddress == null)
|
|
||||||
{
|
|
||||||
// No data was available so return false to indicate this.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Flip the buffer so that we can wrap it.
|
// Flip the buffer so that we can wrap it.
|
||||||
byteBuffer.flip();
|
byteBuffer.flip();
|
||||||
// Create a Netty ChannelByffer by wrapping the ByteBuffer.
|
// Create a Netty ChannelByffer by wrapping the ByteBuffer.
|
||||||
final ChannelBuffer channelBuffer =
|
final ChannelBuffer channelBuffer = ChannelBuffers
|
||||||
ChannelBuffers.wrappedBuffer(byteBuffer);
|
.wrappedBuffer(byteBuffer);
|
||||||
|
|
||||||
logger.debug("ChannelBuffer : " + channelBuffer +
|
logger.debug("ChannelBuffer : " + channelBuffer +
|
||||||
", remoteAdress: " + remoteAddress);
|
", remoteAdress: " + remoteAddress);
|
||||||
@ -378,7 +387,6 @@ class NioUdpWorker implements Runnable {
|
|||||||
fireExceptionCaught(nioDatagramChannel, t);
|
fireExceptionCaught(nioDatagramChannel, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void close(SelectionKey k) {
|
private static void close(SelectionKey k) {
|
||||||
@ -409,11 +417,6 @@ class NioUdpWorker implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param channel
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean scheduleWriteIfNecessary(
|
private static boolean scheduleWriteIfNecessary(
|
||||||
final NioDatagramChannel channel) {
|
final NioDatagramChannel channel) {
|
||||||
final NioUdpWorker worker = channel.worker;
|
final NioUdpWorker worker = channel.worker;
|
||||||
@ -422,8 +425,8 @@ class NioUdpWorker implements Runnable {
|
|||||||
if (workerThread == null || Thread.currentThread() != workerThread) {
|
if (workerThread == null || Thread.currentThread() != workerThread) {
|
||||||
if (channel.writeTaskInTaskQueue.compareAndSet(false, true)) {
|
if (channel.writeTaskInTaskQueue.compareAndSet(false, true)) {
|
||||||
// "add" the channels writeTask to the writeTaskQueue.
|
// "add" the channels writeTask to the writeTaskQueue.
|
||||||
boolean offered =
|
boolean offered = worker.writeTaskQueue
|
||||||
worker.writeTaskQueue.offer(channel.writeTask);
|
.offer(channel.writeTask);
|
||||||
assert offered;
|
assert offered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +455,7 @@ class NioUdpWorker implements Runnable {
|
|||||||
|
|
||||||
Queue<MessageEvent> writeBuffer = channel.writeBufferQueue;
|
Queue<MessageEvent> writeBuffer = channel.writeBufferQueue;
|
||||||
synchronized (channel.writeLock) {
|
synchronized (channel.writeLock) {
|
||||||
// inform the channel that write is inprogres
|
// inform the channel that write is in-progress
|
||||||
channel.inWriteNowLoop = true;
|
channel.inWriteNowLoop = true;
|
||||||
// get the write event.
|
// get the write event.
|
||||||
evt = channel.currentWriteEvent;
|
evt = channel.currentWriteEvent;
|
||||||
@ -477,11 +480,9 @@ class NioUdpWorker implements Runnable {
|
|||||||
try {
|
try {
|
||||||
for (int i = writeSpinCount; i > 0; i --) {
|
for (int i = writeSpinCount; i > 0; i --) {
|
||||||
ChannelBuffer buffer = (ChannelBuffer) evt.getMessage();
|
ChannelBuffer buffer = (ChannelBuffer) evt.getMessage();
|
||||||
int localWrittenBytes =
|
int localWrittenBytes = channel.getDatagramChannel()
|
||||||
channel.getDatagramChannel().send(
|
.send(buffer.toByteBuffer(),
|
||||||
buffer.toByteBuffer(),
|
|
||||||
evt.getRemoteAddress());
|
evt.getRemoteAddress());
|
||||||
//int localWrittenBytes = buf.getBytes( bufIdx, channel.getDatagramChannel(), buf.writerIndex() - bufIdx);
|
|
||||||
if (localWrittenBytes != 0) {
|
if (localWrittenBytes != 0) {
|
||||||
bufIdx += localWrittenBytes;
|
bufIdx += localWrittenBytes;
|
||||||
writtenBytes += localWrittenBytes;
|
writtenBytes += localWrittenBytes;
|
||||||
@ -672,10 +673,14 @@ class NioUdpWorker implements Runnable {
|
|||||||
interestOps &= ~Channel.OP_WRITE;
|
interestOps &= ~Channel.OP_WRITE;
|
||||||
interestOps |= channel.getRawInterestOps() & Channel.OP_WRITE;
|
interestOps |= channel.getRawInterestOps() & Channel.OP_WRITE;
|
||||||
|
|
||||||
switch (CONSTRAINT_LEVEL) {
|
switch (NioProviderMetadata.CONSTRAINT_LEVEL) {
|
||||||
case 0:
|
case 0:
|
||||||
if (channel.getRawInterestOps() != interestOps) {
|
if (channel.getRawInterestOps() != interestOps) {
|
||||||
|
// Set the interesteOps on the SelectionKey
|
||||||
key.interestOps(interestOps);
|
key.interestOps(interestOps);
|
||||||
|
// If the worker thread (the one that that might possibly be blocked
|
||||||
|
// in a select() call) is not the thread executing this method wakeup
|
||||||
|
// the select() operation.
|
||||||
if (Thread.currentThread() != worker.thread &&
|
if (Thread.currentThread() != worker.thread &&
|
||||||
worker.wakenUp.compareAndSet(false, true)) {
|
worker.wakenUp.compareAndSet(false, true)) {
|
||||||
selector.wakeup();
|
selector.wakeup();
|
||||||
@ -687,9 +692,13 @@ class NioUdpWorker implements Runnable {
|
|||||||
case 2:
|
case 2:
|
||||||
if (channel.getRawInterestOps() != interestOps) {
|
if (channel.getRawInterestOps() != interestOps) {
|
||||||
if (Thread.currentThread() == worker.thread) {
|
if (Thread.currentThread() == worker.thread) {
|
||||||
|
// Going to set the interestOps from the same thread.
|
||||||
|
// Set the interesteOps on the SelectionKey
|
||||||
key.interestOps(interestOps);
|
key.interestOps(interestOps);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
|
// Going to set the interestOps from a different thread
|
||||||
|
// and some old provides will need synchronization.
|
||||||
worker.selectorGuard.readLock().lock();
|
worker.selectorGuard.readLock().lock();
|
||||||
try {
|
try {
|
||||||
if (worker.wakenUp.compareAndSet(false, true)) {
|
if (worker.wakenUp.compareAndSet(false, true)) {
|
||||||
@ -767,8 +776,6 @@ class NioUdpWorker implements Runnable {
|
|||||||
throw new ChannelException(
|
throw new ChannelException(
|
||||||
"Failed to register a socket to the selector.", e);
|
"Failed to register a socket to the selector.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
//fireChannelBound(channel, localAddress);
|
|
||||||
fireChannelConnected(channel, localAddress);
|
fireChannelConnected(channel, localAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,9 @@ import org.junit.Test;
|
|||||||
/**
|
/**
|
||||||
* Unit test for {@link NioDatagramChannel}
|
* Unit test for {@link NioDatagramChannel}
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Daniel Bevenius (dbevenius@jboss.com)
|
||||||
|
* @version $Rev$, $Date$
|
||||||
*/
|
*/
|
||||||
public class NioDatagramChannelTest {
|
public class NioDatagramChannelTest {
|
||||||
private static Channel sc;
|
private static Channel sc;
|
||||||
@ -48,9 +50,9 @@ public class NioDatagramChannelTest {
|
|||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setupChannel() {
|
public static void setupChannel() {
|
||||||
final ServerBootstrap sb =
|
final NioDatagramChannelFactory channelFactory = new NioDatagramChannelFactory(
|
||||||
new ServerBootstrap(new NioDatagramChannelFactory(Executors
|
Executors.newCachedThreadPool());
|
||||||
.newCachedThreadPool()));
|
final ServerBootstrap sb = new ServerBootstrap(channelFactory);
|
||||||
inetSocketAddress = new InetSocketAddress("localhost", 9999);
|
inetSocketAddress = new InetSocketAddress("localhost", 9999);
|
||||||
sc = sb.bind(inetSocketAddress);
|
sc = sb.bind(inetSocketAddress);
|
||||||
final SimpleHandler handler = new SimpleHandler();
|
final SimpleHandler handler = new SimpleHandler();
|
||||||
@ -59,8 +61,8 @@ public class NioDatagramChannelTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void checkBoundPort() throws Throwable {
|
public void checkBoundPort() throws Throwable {
|
||||||
final InetSocketAddress socketAddress =
|
final InetSocketAddress socketAddress = (InetSocketAddress) sc
|
||||||
(InetSocketAddress) sc.getLocalAddress();
|
.getLocalAddress();
|
||||||
assertEquals(9999, socketAddress.getPort());
|
assertEquals(9999, socketAddress.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,14 +81,14 @@ public class NioDatagramChannelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clientBootstrap() {
|
public void clientBootstrap() {
|
||||||
final ClientBootstrap bootstrap =
|
final NioDatagramChannelFactory channelFactory = new NioDatagramChannelFactory(
|
||||||
new ClientBootstrap(new NioDatagramChannelFactory(Executors
|
Executors.newCachedThreadPool());
|
||||||
.newCachedThreadPool()));
|
final ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
|
||||||
bootstrap.getPipeline().addLast("test", new SimpleHandler());
|
bootstrap.getPipeline().addLast("test", new SimpleHandler());
|
||||||
bootstrap.setOption("tcpNoDelay", true);
|
bootstrap.setOption("tcpNoDelay", true);
|
||||||
bootstrap.setOption("keepAlive", true);
|
bootstrap.setOption("keepAlive", true);
|
||||||
InetSocketAddress clientAddress =
|
InetSocketAddress clientAddress = new InetSocketAddress("localhost",
|
||||||
new InetSocketAddress("localhost", 8888);
|
8888);
|
||||||
bootstrap.setOption("localAddress", clientAddress);
|
bootstrap.setOption("localAddress", clientAddress);
|
||||||
|
|
||||||
ChannelFuture ccf = bootstrap.connect(inetSocketAddress);
|
ChannelFuture ccf = bootstrap.connect(inetSocketAddress);
|
||||||
@ -94,9 +96,8 @@ public class NioDatagramChannelTest {
|
|||||||
|
|
||||||
Channel cc = ccf.getChannel();
|
Channel cc = ccf.getChannel();
|
||||||
final String payload = "client payload";
|
final String payload = "client payload";
|
||||||
ChannelFuture write =
|
ChannelFuture write = cc.write(ChannelBuffers.wrappedBuffer(payload
|
||||||
cc.write(ChannelBuffers.wrappedBuffer(payload.getBytes(), 0,
|
.getBytes(), 0, payload.length()));
|
||||||
payload.length()));
|
|
||||||
write.awaitUninterruptibly();
|
write.awaitUninterruptibly();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,9 +112,8 @@ public class NioDatagramChannelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void sendRecive(final String expectedPayload) throws IOException {
|
private void sendRecive(final String expectedPayload) throws IOException {
|
||||||
final UdpClient udpClient =
|
final UdpClient udpClient = new UdpClient(inetSocketAddress
|
||||||
new UdpClient(inetSocketAddress.getAddress(), inetSocketAddress
|
.getAddress(), inetSocketAddress.getPort());
|
||||||
.getPort());
|
|
||||||
final DatagramPacket dp = udpClient.send(expectedPayload.getBytes());
|
final DatagramPacket dp = udpClient.send(expectedPayload.getBytes());
|
||||||
|
|
||||||
dp.setData(new byte[expectedPayload.length()]);
|
dp.setData(new byte[expectedPayload.length()]);
|
||||||
|
Loading…
Reference in New Issue
Block a user