Author: elecharny
Date: Tue Jun 16 09:53:45 2009
New Revision: 785134

URL: http://svn.apache.org/viewvc?rev=785134&view=rev
Log:
Applied the select fiox on this branch

Modified:
    
mina/branches/select-fix/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
    
mina/branches/select-fix/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
    
mina/branches/select-fix/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java

Modified: 
mina/branches/select-fix/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
URL: 
http://svn.apache.org/viewvc/mina/branches/select-fix/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java?rev=785134&r1=785133&r2=785134&view=diff
==============================================================================
--- 
mina/branches/select-fix/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
 (original)
+++ 
mina/branches/select-fix/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
 Tue Jun 16 09:53:45 2009
@@ -29,6 +29,7 @@
 import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.mina.core.buffer.IoBuffer;
@@ -98,6 +99,8 @@
     private volatile boolean disposed;
 
     private final DefaultIoFuture disposalFuture = new DefaultIoFuture(null);
+    
+    protected AtomicBoolean wakeupCalled = new AtomicBoolean(false);
 
     /**
      * Create an {...@link AbstractPollingIoProcessor} with the given 
{...@link Executor}
@@ -403,6 +406,14 @@
         // can be activated immediately. 
         wakeup();
     }
+    
+    
+    /**
+     * In the case we are using the java select() method, this method is
+     * used to trash the buggy selector and create a new one, registring
+     * all the sockets on it.
+     */
+    abstract protected void registerNewSelector() throws IOException;
 
     /**
      * Loops over the new sessions blocking queue and returns
@@ -906,18 +917,51 @@
 
             for (;;) {
                 try {
+                    long t0 = System.currentTimeMillis();
                     // This select has a timeout so that we can manage
                     // idle session when we get out of the select every
                     // second. (note : this is a hack to avoid creating
                     // a dedicated thread).
                     int selected = select(SELECT_TIMEOUT);
 
+                    synchronized(wakeupCalled) {
+                        long t1 = System.currentTimeMillis();
+                        
+                        if (selected == 0) {
+                            if ( ! wakeupCalled.get()) {
+                                if ((t1 - t0) < 100) {
+                                    System.out.println("Create a new selector. 
Selected is 0, delta = " + (t1 - t0));
+                                    // Ok, we are hit by the nasty epoll 
spinning.
+                                    // Basically, tehre is a race condition 
which cause 
+                                    // a closing file descriptor not to be 
considered as 
+                                    // available as a selected channel, but it 
stopped
+                                    // the select. The next time we will call 
select(),
+                                    // it will exit immediately for the same 
reason, 
+                                    // and do so forever, consuming 100% CPU.
+                                    // We have to destroy the selector, and 
register all 
+                                    // the socket on a new one.
+                                    registerNewSelector();
+                                    
+                                    // and continue the loop
+                                    //continue;
+                                }
+                            } else {
+                                //System.out.println("Waited one second");
+                            }
+                        } else {
+                            //System.out.println("Nb selected : " + selected);
+                        }
+    
+                        wakeupCalled.getAndSet(false);
+                    }
+
                     nSessions += handleNewSessions();
                     updateTrafficMask();
 
                     // Now, if we have had some incoming or outgoing events,
                     // deal with them
                     if (selected > 0) {
+                        //System.out.println( "Proccessing ...");
                         process();
                     }
 

Modified: 
mina/branches/select-fix/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
URL: 
http://svn.apache.org/viewvc/mina/branches/select-fix/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java?rev=785134&r1=785133&r2=785134&view=diff
==============================================================================
--- 
mina/branches/select-fix/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
 (original)
+++ 
mina/branches/select-fix/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
 Tue Jun 16 09:53:45 2009
@@ -40,7 +40,9 @@
  */
 public final class NioProcessor extends AbstractPollingIoProcessor<NioSession> 
{
     /** The selector associated with this processor */
-    private final Selector selector;
+    private Selector selector;
+    
+    private Object lock = new Object();
 
     /**
      * 
@@ -80,7 +82,10 @@
 
     @Override
     protected void wakeup() {
-        selector.wakeup();
+        synchronized(wakeupCalled) {
+            wakeupCalled.getAndSet(true);
+            selector.wakeup();
+        }
     }
 
     @Override
@@ -109,6 +114,32 @@
         }
         ch.close();
     }
+    
+    
+    /**
+     * In the case we are using the java select() method, this method is
+     * used to trash the buggy selector and create a new one, registring
+     * all the sockets on it.
+     */
+    protected void registerNewSelector() throws IOException {
+        synchronized (selector) {
+            Set<SelectionKey> keys = selector.keys();
+            
+            // Open a new selector
+            Selector newSelector = Selector.open();
+            
+            for ( SelectionKey key:keys ) {
+                SelectableChannel ch = key.channel();
+                ch.register(newSelector, key.interestOps());
+            }
+
+            selector.close();
+            selector = newSelector;
+        }
+        
+        
+    }
+    
 
     @Override
     protected SessionState state(NioSession session) {

Modified: 
mina/branches/select-fix/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java
URL: 
http://svn.apache.org/viewvc/mina/branches/select-fix/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java?rev=785134&r1=785133&r2=785134&view=diff
==============================================================================
--- 
mina/branches/select-fix/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java
 (original)
+++ 
mina/branches/select-fix/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java
 Tue Jun 16 09:53:45 2009
@@ -455,4 +455,13 @@
                 org.apache.tomcat.jni.Error.strerror(-code) +
                 " (code: " + code + ")");
     }
+
+    /**
+     * In the case we are using the java select() method, this method is
+     * used to trash the buggy selector and create a new one, registring
+     * all the sockets on it.
+     */
+    protected void registerNewSelector() {
+        // Do nothing
+    }
 }
\ No newline at end of file


Reply via email to