[
https://issues.apache.org/jira/browse/DIRMINA-1076?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16375915#comment-16375915
]
Jonathan Valliere commented on DIRMINA-1076:
--------------------------------------------
In the previous post, I mentioned the possibility of totally removing the
{{nSession}} state.
*Option 3*
Completely removes the {{nSession}} state because it is corruptible. Relies
entirely on {{selector.keys().size()}} for the state. This is actually the
most simple of all the alternatives as it requires no new atomic mechanisms.
Only drawback is that it might take longer to {{dispose()}} the {{IoProcessor}}
due the extra {{select()}} cycle that must occur to update the session count.
{code:java}
diff --git
a/mina-core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
b/mina-core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
index 79885fa..c807bf1 100644
---
a/mina-core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
+++
b/mina-core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
@@ -240,6 +240,13 @@
* @return {@link Iterator} of {@link IoSession}
*/
protected abstract Iterator<S> allSessions();
+
+ /**
+ * Get the number of {@Link IoSession} polled by this {@Link IoProcessor}
+ *
+ * @return the number of sessions attached to this {@Link IoProcessor}
+ */
+ protected abstract int allSessionsCount();
/**
* Get an {@link Iterator} for the list of {@link IoSession} found selected
@@ -596,7 +603,6 @@
public void run() {
assert processorRef.get() == this;
- int nSessions = 0;
lastIdleCheckTime = System.currentTimeMillis();
int nbTries = 10;
@@ -641,9 +647,31 @@
} else {
nbTries = 10;
}
-
+
// Manage newly created session first
- nSessions += handleNewSessions();
+ if(handleNewSessions() == 0) {
+ // Get a chance to exit the infinite loop if there are
no
+ // more sessions on this Processor
+ if (allSessionsCount() == 0) {
+ processorRef.set(null);
+
+ if (newSessions.isEmpty() && isSelectorEmpty()) {
+ // newSessions.add() precedes startupProcessor
+ assert processorRef.get() != this;
+ break;
+ }
+
+ assert processorRef.get() != this;
+
+ if (!processorRef.compareAndSet(null, this)) {
+ // startupProcessor won race, so must exit
processor
+ assert processorRef.get() != this;
+ break;
+ }
+
+ assert processorRef.get() == this;
+ }
+ }
updateTrafficMask();
@@ -654,39 +682,17 @@
// the MDCFilter test...
process();
}
-
+
// Write the pending requests
long currentTime = System.currentTimeMillis();
flush(currentTime);
-
- // And manage removed sessions
- nSessions -= removeSessions();
-
+
// Last, not least, send Idle events to the idle sessions
notifyIdleSessions(currentTime);
-
- // Get a chance to exit the infinite loop if there are no
- // more sessions on this Processor
- if (nSessions == 0) {
- processorRef.set(null);
-
- if (newSessions.isEmpty() && isSelectorEmpty()) {
- // newSessions.add() precedes startupProcessor
- assert processorRef.get() != this;
- break;
- }
-
- assert processorRef.get() != this;
-
- if (!processorRef.compareAndSet(null, this)) {
- // startupProcessor won race, so must exit
processor
- assert processorRef.get() != this;
- break;
- }
-
- assert processorRef.get() == this;
- }
-
+
+ // And manage removed sessions
+ removeSessions();
+
// Disconnect all sessions immediately if disposal has been
// requested so that we exit this loop eventually.
if (isDisposing()) {
@@ -702,9 +708,7 @@
}
}
- if (hasKeys) {
- wakeup();
- }
+ wakeup();
}
} catch (ClosedSelectorException cse) {
// If the selector has been closed, we can exit the loop
diff --git
a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
index 3b0fa40..9948d7a 100644
---
a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
+++
b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
@@ -159,6 +159,12 @@
selectorLock.readLock().unlock();
}
}
+
+ @Override
+ protected int allSessionsCount()
+ {
+ return selector.keys().size();
+ }
@SuppressWarnings("synthetic-access")
@Override
diff --git
a/mina-core/src/test/java/org/apache/mina/transport/socket/nio/PollingIoProcessorTest.java
b/mina-core/src/test/java/org/apache/mina/transport/socket/nio/PollingIoProcessorTest.java
index 379f55b..f289aaf 100644
---
a/mina-core/src/test/java/org/apache/mina/transport/socket/nio/PollingIoProcessorTest.java
+++
b/mina-core/src/test/java/org/apache/mina/transport/socket/nio/PollingIoProcessorTest.java
@@ -61,6 +61,11 @@
protected Iterator<NioSession> allSessions() {
return proc.allSessions();
}
+
+ @Override
+ protected int allSessionsCount() {
+ return proc.allSessionsCount();
+ }
@Override
protected void destroy(NioSession session) throws Exception {
{code}
> Leaking NioProcessors/NioSocketConnectors hanging in call to dispose
> --------------------------------------------------------------------
>
> Key: DIRMINA-1076
> URL: https://issues.apache.org/jira/browse/DIRMINA-1076
> Project: MINA
> Issue Type: Bug
> Affects Versions: 2.0.16
> Reporter: Christoph John
> Assignee: Jonathan Valliere
> Priority: Major
> Attachments: mina-dispose-hang.txt, mina-test-log.txt,
> mina-test-patch.txt
>
>
> Follow-up to mailing list discussion.
> I was now able to reproduce the problem with a MINA test. Or let's say I did
> the brute-force approach by re-running one test in an endless loop.
> I have attached a patch of AbstractIoServiceTest (against
> [https://github.com/apache/mina/tree/2.0]) and a stack trace. After a few
> loops the test is stuck. You can see a lot of threads hanging in dispose()
> and the test is stuck when it tries to dispose the acceptor.
>
> What is a little strange is that the javadoc says that
> connector.dispose(TRUE) should not be called from an IoFutureListener, but in
> the test it is done anyway. However, changing the parameter to FALSE does not
> help either.
>
> Is there anything that can be done to prevent this hang?
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)