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