[ 
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)

Reply via email to