Resource not being cleaned properly in NioSocketConnector and NioProcessor
classes
----------------------------------------------------------------------------------
Key: DIRMINA-786
URL: https://issues.apache.org/jira/browse/DIRMINA-786
Project: MINA
Issue Type: Bug
Components: Core
Affects Versions: 2.0.0-RC1
Environment: linux
Reporter: Chandrika R
I have a situation where I created NioSocketConnector object, connect to http
service, send a request, process the response and close. I find that when an
instance of NioSocketConnector object is created with default parameters and
closed subsequently, the Selector objects created in NioSocketConnector and
NioProcessor do not get closed. When this happens repeatedly, then after a
while, the exception java.io.IOException: Too many open files is thrown. I
found two issues where there are potential leaks.
1. In SimpleIoProcessorPool.java, when an instance of IoProcessor class is
being created for pool[0] as below, when the first instance is created
successfully, the next instance creation should check if pool[0] is null.
try {
try {
processorConstructor = processorType
.getConstructor(ExecutorService.class);
pool[0] = processorConstructor.newInstance(executor);
} catch (NoSuchMethodException e) {
// To the next step...
}
try {
processorConstructor =
processorType.getConstructor(Executor.class);
pool[0] = processorConstructor.newInstance(executor);
} catch (NoSuchMethodException e) {
// To the next step...
}
try {
processorConstructor = processorType.getConstructor();
usesExecutorArg = false;
pool[0] = processorConstructor.newInstance();
} catch (NoSuchMethodException e) {
// To the next step...
}
2. When SimpleIoProcessorPool object is destroyed, the processor dispose calls
are invoked but the executor service is shutdown immediately and hence the
AbstractPollingIoProcessor.Processor.run is never invoked to clean up the
resources. Same issue is seen in AbstractPollingIoConnector implementation also.
public final void dispose() {
if (disposed) {
return;
}
synchronized (disposalLock) {
if (!disposing) {
disposing = true;
for (int i = pool.length - 1; i >= 0; i--) {
//if (pool[i] == null || pool[i].isDisposing()) {
if (pool[i] == null) {
continue;
}
try {
System.out.println("Disposing " + pool[i]);
pool[i].dispose();
} catch (Exception e) {
LOGGER.warn("Failed to dispose a "
+ pool[i].getClass().getSimpleName()
+ " at index " + i + ".", e);
} finally {
pool[i] = null;
}
}
if (createdExecutor) {
((ExecutorService) executor).shutdown();
}
}
}
I created my own Executor and SimpleIoProcessorPool instances which I pass to
NioSocketConnector as an alternate solution for issue 2.
Thanks
Chandrika
Exception log:
at sun.nio.ch.FileDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:21)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:233)
at sun.nio.ch.IOUtil.read(IOUtil.java:206)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:236)
at
org.apache.mina.transport.socket.nio.NioProcessor.read(NioProcessor.java:202)
at
org.apache.mina.transport.socket.nio.NioProcessor.read(NioProcessor.java:42)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:620)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:598)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:587)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:61)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:969)
at
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
org.apache.mina.core.RuntimeIoException: Failed to create a new instance of
org.apache.mina.transport.socket.nio.NioProcessor
at
org.apache.mina.core.service.SimpleIoProcessorPool.<init>(SimpleIoProcessorPool.java:171)
at
org.apache.mina.core.service.SimpleIoProcessorPool.<init>(SimpleIoProcessorPool.java:104)
at
org.apache.mina.core.polling.AbstractPollingIoConnector.<init>(AbstractPollingIoConnector.java:93)
at
org.apache.mina.transport.socket.nio.NioSocketConnector.<init>(NioSocketConnector.java:55)
at org.red5.server.net.muxrtmp.HttpClient.connect(HttpClient.java:76)
at
org.red5.server.net.muxrtmp.MuxRTMPMinaConnection.connectToHttpService(MuxRTMPMinaConnection.java:102)
at
org.red5.server.net.muxrtmp.HttpHandler.messageReceived(HttpHandler.java:64)
at
org.red5.server.net.muxrtmp.MuxRTMPSMinaIoHandler.messageReceived(MuxRTMPSMinaIoHandler.java:89)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:713)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:46)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:793)
at
org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:71)
at org.apache.mina.core.session.IoEvent.run(IoEvent.java:63)
at
org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTask(OrderedThreadPoolExecutor.java:780)
at
org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTasks(OrderedThreadPoolExecutor.java:772)
at
org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.run(OrderedThreadPoolExecutor.java:714)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedConstructorAccessor37.newInstance(Unknown
Source)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at
org.apache.mina.core.service.SimpleIoProcessorPool.<init>(SimpleIoProcessorPool.java:156)
... 17 more
Caused by: org.apache.mina.core.RuntimeIoException: Failed to open a selector.
at
org.apache.mina.transport.socket.nio.NioProcessor.<init>(NioProcessor.java:58)
... 21 more
Caused by: java.io.IOException: Too many open files
at sun.nio.ch.IOUtil.initPipe(Native Method)
at sun.nio.ch.EPollSelectorImpl.<init>(EPollSelectorImpl.java:49)
at
sun.nio.ch.EPollSelectorProvider.openSelector(EPollSelectorProvider.java:18)
at java.nio.channels.Selector.open(Selector.java:209)
at
org.apache.mina.transport.socket.nio.NioProcessor.<init>(NioProcessor.java:56)
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.