Author: remy.maucherat(a)jboss.com
Date: 2013-11-06 08:05:56 -0500 (Wed, 06 Nov 2013)
New Revision: 2302
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java
Log:
- Experiment with dropping recycling of the various runnables used for the processor,
completion handlers, and other small utility structures (sendfile and channels in the
"poller").
- Remove connection tracking (jio doesn't do it, so I don't understand why it is
needed, closing the main channel is probably enough when stopping).
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java 2013-11-06
09:38:04 UTC (rev 2301)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java 2013-11-06
13:05:56 UTC (rev 2302)
@@ -57,9 +57,6 @@
public class NioEndpoint extends AbstractEndpoint {
private AsynchronousServerSocketChannel listener;
- private ConcurrentHashMap<Long, NioChannel> connections;
- private ConcurrentLinkedQueue<ChannelProcessor> recycledChannelProcessors;
- private ConcurrentLinkedQueue<HandshakeHandler> recycledHandshakeProcessors;
/**
* Handling of accepted sockets.
@@ -182,18 +179,6 @@
this.threadFactory = new DefaultThreadFactory(getName() + "-",
threadPriority);
}
- if (this.connections == null) {
- this.connections = new ConcurrentHashMap<Long, NioChannel>();
- }
-
- if (this.recycledChannelProcessors == null) {
- this.recycledChannelProcessors = new ConcurrentLinkedQueue<ChannelProcessor>();
- }
-
- if (this.recycledHandshakeProcessors == null) {
- this.recycledHandshakeProcessors = new
ConcurrentLinkedQueue<HandshakeHandler>();
- }
-
// If the executor is not set, create it with a fixed thread pool
if (this.executor == null) {
this.executor = Executors.newFixedThreadPool(this.maxThreads, this.threadFactory);
@@ -307,25 +292,9 @@
this.eventPoller.destroy();
}
- // Closing all alive connections
- for (NioChannel ch : this.connections.values()) {
- try {
- ch.close();
- } catch (Throwable t) {
- // Nothing to do
- }
- }
- // Remove all connections
- this.connections.clear();
// Destroy the server socket channel factory
this.serverSocketChannelFactory.destroy();
this.serverSocketChannelFactory = null;
- // Destroy all recycled channel processors
- this.recycledChannelProcessors.clear();
- this.recycledChannelProcessors = null;
- // Destroy all recycled handshake processors
- this.recycledHandshakeProcessors.clear();
- this.recycledHandshakeProcessors = null;
// Shut down the executor
((ExecutorService) this.executor).shutdown();
@@ -481,8 +450,7 @@
return false;
}
try {
- ChannelProcessor processor = getChannelProcessor(channel, status);
- this.executor.execute(processor);
+ this.executor.execute(new ChannelProcessor(channel, status));
return true;
} catch (Throwable t) {
// This means we got an OOM or similar creating a thread, or that
@@ -498,8 +466,7 @@
*/
private boolean handshake(NioChannel channel) {
try {
- HandshakeHandler processor = getHandshakeProcessor(channel);
- this.executor.execute(processor);
+ this.executor.execute(new HandshakeHandler(channel));
return true;
} catch (Throwable t) {
// This means we got an OOM or similar creating a thread, or that
@@ -510,54 +477,6 @@
}
/**
- * @return peek a processor from the recycled processors list
- */
- private ChannelProcessor getChannelProcessor(NioChannel channel, SocketStatus status) {
- ChannelProcessor processor = this.recycledChannelProcessors.poll();
- if (processor == null) {
- processor = new ChannelProcessor(channel, status);
- } else {
- processor.setChannel(channel);
- processor.setStatus(status);
- }
- return processor;
- }
-
- /**
- * @return peek a handshake processor from the recycled processors list
- */
- private HandshakeHandler getHandshakeProcessor(NioChannel channel) {
- HandshakeHandler processor = this.recycledHandshakeProcessors.poll();
- if (processor == null) {
- processor = new HandshakeHandler(channel);
- } else {
- processor.setChannel(channel);
- }
- return processor;
- }
-
- /**
- * Try to add the specified channel to the list of connections.
- *
- * @param channel
- * the channel to be added
- * @return <tt>true</tt> if the channel is added successfully, else
- * <tt>false</tt>
- */
- private boolean addChannel(NioChannel channel) {
- if (this.counter.get() < this.maxConnections && channel.isOpen()) {
- if (this.connections.get(channel.getId()) == null
- || this.connections.get(channel.getId()).isClosed()) {
- this.connections.put(channel.getId(), channel);
- this.counter.incrementAndGet();
- return true;
- }
- }
-
- return false;
- }
-
- /**
* Getter for serverSocketChannelFactory
*
* @return the serverSocketChannelFactory
@@ -590,10 +509,6 @@
channel.close();
} catch (IOException e) {
CoyoteLogger.UTIL_LOGGER.errorClosingSocket(e);
- } finally {
- if (this.connections.remove(channel.getId()) != null) {
- this.counter.decrementAndGet();
- }
}
}
}
@@ -603,7 +518,7 @@
* from the pool, else <tt>null</tt>
*/
public SendfileData getSendfileData() {
- return this.sendfile != null ? this.sendfile.getSendfileData() : new SendfileData();
+ return new SendfileData();
}
/**
@@ -640,7 +555,7 @@
// channel
final NioChannel channel = serverSocketChannelFactory.acceptChannel(listener);
boolean ok = false;
- if (addChannel(channel) && setChannelOptions(channel) &&
channel.isOpen()) {
+ if (setChannelOptions(channel) && channel.isOpen()) {
if (channel.isSecure()) {
handshake(channel);
ok = true;
@@ -709,29 +624,9 @@
} catch (Exception exp) {
CoyoteLogger.UTIL_LOGGER.errorProcessingChannelDebug(exp);
closeChannel(channel);
- } finally {
- this.recycle();
}
}
- /**
- * Recycle the handshake processor
- */
- private void recycle() {
- this.channel = null;
- if (recycledHandshakeProcessors != null) {
- recycledHandshakeProcessors.offer(this);
- }
- }
-
- /**
- * Setter for the channel
- *
- * @param channel
- */
- public void setChannel(NioChannel channel) {
- this.channel = channel;
- }
}
/**
@@ -802,15 +697,6 @@
}
/**
- * Recycle this channel info for next use
- */
- public void recycle() {
- this.channel = null;
- this.timeout = 0;
- this.flags = 0;
- }
-
- /**
* @return the read flag
*/
public boolean read() {
@@ -1036,45 +922,9 @@
}
} catch (Throwable th) {
CoyoteLogger.UTIL_LOGGER.errorProcessingChannelWithException(th);
- } finally {
- this.recycle();
}
}
- /**
- * Reset this channel processor
- */
- protected void recycle() {
- this.channel = null;
- this.status = null;
- if (recycledChannelProcessors != null) {
- recycledChannelProcessors.offer(this);
- }
- }
-
- /**
- *
- * @param channel
- * @param status
- */
- protected void setup(NioChannel channel, SocketStatus status) {
- this.channel = channel;
- this.status = status;
- }
-
- /**
- * @param status
- */
- public void setStatus(SocketStatus status) {
- this.status = status;
- }
-
- /**
- * @param channel
- */
- public void setChannel(NioChannel channel) {
- this.channel = channel;
- }
}
/**
@@ -1092,8 +942,6 @@
protected long lastMaintain = System.currentTimeMillis();
protected ConcurrentHashMap<Long, ChannelInfo> channelList;
- protected ConcurrentLinkedQueue<ChannelInfo> recycledChannelList;
- private ConcurrentLinkedQueue<CompletionHandler<Integer, NioChannel>>
recycledCompletionHandlers;
private Object mutex;
private int size;
@@ -1176,8 +1024,7 @@
* @param id
*/
protected boolean remove(long id) {
- ChannelInfo info = this.channelList.remove(id);
- return offer(info);
+ return this.channelList.remove(id) != null;
}
/**
@@ -1202,8 +1049,6 @@
public void init() {
this.mutex = new Object();
this.channelList = new ConcurrentHashMap<Long, ChannelInfo>(this.size);
- this.recycledChannelList = new ConcurrentLinkedQueue<ChannelInfo>();
- this.recycledCompletionHandlers = new
ConcurrentLinkedQueue<CompletionHandler<Integer, NioChannel>>();
}
/**
@@ -1212,87 +1057,42 @@
public void destroy() {
synchronized (this.mutex) {
this.channelList.clear();
- this.recycledChannelList.clear();
- this.recycledCompletionHandlers.clear();
this.mutex.notifyAll();
}
}
/**
+ * Create a completion handler for read.
*
- * @return
- */
- protected ChannelInfo poll() {
- ChannelInfo info = this.recycledChannelList.poll();
- if (info == null) {
- info = new ChannelInfo();
- }
- return info;
- }
-
- /**
- * Recycle the the {@link ChannelInfo}
- *
- * @param info
- */
- protected boolean offer(ChannelInfo info) {
- if (info != null) {
- info.recycle();
- return this.recycledChannelList.offer(info);
- }
- return false;
- }
-
- /**
- * Peek a {@link java.nio.CompletionHandler} from the list of recycled
- * handlers. If the list is empty, create a new one and return it.
- *
* @return a reference of {@link java.nio.CompletionHandler}
*/
private CompletionHandler<Integer, NioChannel> getCompletionHandler() {
- CompletionHandler<Integer, NioChannel> handler =
this.recycledCompletionHandlers.poll();
- if (handler == null) {
- handler = new CompletionHandler<Integer, NioChannel>() {
+ CompletionHandler<Integer, NioChannel> handler = new
CompletionHandler<Integer, NioChannel>() {
+ @Override
+ public void completed(Integer nBytes, NioChannel attach) {
+ if (nBytes < 0) {
+ failed(new ClosedChannelException(), attach);
+ } else {
+ remove(attach);
+ if (!processChannel(attach, SocketStatus.OPEN_READ)) {
+ closeChannel(attach);
+ }
+ }
+ }
- @Override
- public void completed(Integer nBytes, NioChannel attach) {
- if (nBytes < 0) {
- failed(new ClosedChannelException(), attach);
- } else {
- remove(attach);
- if (!processChannel(attach, SocketStatus.OPEN_READ)) {
- closeChannel(attach);
- }
- // Recycle the completion handler
- recycleHanlder(this);
- }
- }
+ @Override
+ public void failed(Throwable exc, NioChannel attach) {
+ remove(attach);
+ if (!processChannel(attach, SocketStatus.ERROR)) {
+ closeChannel(attach);
+ }
+ }
+ };
- @Override
- public void failed(Throwable exc, NioChannel attach) {
- remove(attach);
- if (!processChannel(attach, SocketStatus.ERROR)) {
- closeChannel(attach);
- }
- // Recycle the completion handler
- recycleHanlder(this);
- }
- };
- }
-
return handler;
}
/**
- * Recycle the {@link java.nio.CompletionHandler}
- *
- * @param handler
- */
- private void recycleHanlder(CompletionHandler<Integer, NioChannel> handler) {
- this.recycledCompletionHandlers.offer(handler);
- }
-
- /**
* Add the channel to the list of channels
*
* @param channel
@@ -1310,7 +1110,7 @@
ChannelInfo info = this.channelList.get(channel.getId());
if (info == null) {
- info = poll();
+ info = new ChannelInfo();
info.channel = channel;
info.flags = flag;
this.channelList.put(channel.getId(), info);
@@ -1440,25 +1240,6 @@
}
/**
- * Recycle this {@code SendfileData}
- */
- protected void recycle() {
- this.start = 0;
- this.end = 0;
- this.pos = 0;
- this.channel = null;
- this.keepAlive = false;
- if (this.fileChannel != null && this.fileChannel.isOpen()) {
- try {
- this.fileChannel.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- this.fileChannel = null;
- }
-
- /**
* Getter for fileName
*
* @return the fileName
@@ -1584,7 +1365,6 @@
protected int size;
protected ConcurrentLinkedQueue<SendfileData> fileDatas;
- protected ConcurrentLinkedQueue<SendfileData> recycledFileDatas;
protected AtomicInteger counter;
private Object mutex;
@@ -1644,7 +1424,6 @@
this.mutex = new Object();
this.counter = new AtomicInteger(0);
this.fileDatas = new ConcurrentLinkedQueue<SendfileData>();
- this.recycledFileDatas = new ConcurrentLinkedQueue<SendfileData>();
}
/**
@@ -1655,33 +1434,13 @@
// To unlock the
this.counter.incrementAndGet();
this.fileDatas.clear();
- this.recycledFileDatas.clear();
// Unlock threads waiting for this monitor
this.mutex.notifyAll();
}
}
/**
- * @param data
- */
- public void recycleSendfileData(SendfileData data) {
- data.recycle();
- this.recycledFileDatas.offer(data);
- }
-
- /**
- * Poll the head of the recycled object list if it is not empty, else
- * create a new one.
*
- * @return a {@code SendfileData}
- */
- public SendfileData getSendfileData() {
- SendfileData data = this.recycledFileDatas.poll();
- return data == null ? new SendfileData() : data;
- }
-
- /**
- *
* @param data
* @throws Exception
*/
@@ -1711,8 +1470,6 @@
attachment.pos += nw;
if (attachment.pos >= attachment.end) {
- // All requested bytes were sent, recycle it
- recycleSendfileData(attachment);
return;
}
@@ -1765,8 +1522,6 @@
data.fileChannel.close();
add(data);
}
- } else {
- recycleSendfileData(data);
}
}