You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2006/06/22 21:05:03 UTC

svn commit: r416444 [1/2] - in /tomcat/tc6.0.x/trunk/java/org/apache: coyote/http11/Http11NioProcessor.java coyote/http11/InternalNioInputBuffer.java tomcat/util/net/NioEndpoint.java

Author: fhanik
Date: Thu Jun 22 12:05:02 2006
New Revision: 416444

URL: http://svn.apache.org/viewvc?rev=416444&view=rev
Log:
Fix so that we don't do a busy read, instead we are properly doing a NIO poller wait
This way, we can achieve blocking read, without wasting CPU cycles.
Since we are using Java 5, I will be changing this implementation from using synchronized to using the Exchanger, this is also to avoid anyi locks that can happen. For example, in the current implementation the poller can call notify before we have had a chance to call wait

Modified:
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java

Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=416444&r1=416443&r2=416444&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Thu Jun 22 12:05:02 2006
@@ -90,8 +90,8 @@
             readTimeout = timeout;
             //readTimeout = -1;
         }
-        inputBuffer = new InternalNioInputBuffer(request, headerBufferSize,
-                readTimeout);
+        inputBuffer = new InternalNioInputBuffer(request, headerBufferSize,readTimeout);
+        inputBuffer.setPoller(endpoint.getPoller());
         request.setInputBuffer(inputBuffer);
 
         response = new Response();

Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?rev=416444&r1=416443&r2=416444&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Thu Jun 22 12:05:02 2006
@@ -28,6 +28,10 @@
 import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.http.MimeHeaders;
 import org.apache.tomcat.util.res.StringManager;
+import java.nio.channels.Selector;
+import java.nio.channels.SelectionKey;
+import org.apache.tomcat.util.net.NioEndpoint.KeyAttachment;
+import org.apache.tomcat.util.net.NioEndpoint.Poller;
 
 /**
  * Implementation of InputBuffer which provides HTTP request header parsing as
@@ -183,7 +187,7 @@
      * header.
      */
     protected long readTimeout;
-
+    private Poller poller;
 
     // ------------------------------------------------------------- Properties
 
@@ -203,6 +207,9 @@
         return socket;
     }
 
+    public Poller getPoller() {
+        return poller;
+    }
 
     /**
      * Add an input filter to the filter library.
@@ -272,6 +279,9 @@
         this.swallowInput = swallowInput;
     }
 
+    public void setPoller(Poller poller) {
+        this.poller = poller;
+    }
 
     // --------------------------------------------------------- Public Methods
 
@@ -551,7 +561,20 @@
                 return false;
             }
             timedOut = (readTimeout != -1) && ((System.currentTimeMillis()-start)>this.readTimeout);
-            //if ( !timedOut && nRead == 0 ) try {Thread.sleep(5);}catch ( Exception x ) {}
+            if ( !timedOut && nRead == 0 ) 
+                try {
+                    final SelectionKey key = socket.keyFor(poller.getSelector());
+                    KeyAttachment att = (KeyAttachment)key.attachment();
+                    att.setWakeUp(true);
+                    
+                    poller.addEvent(
+                        new Runnable() {
+                            public void run() {
+                                if ( key != null ) key.interestOps(SelectionKey.OP_READ);
+                            }
+                    });
+                    synchronized (att.getMutex()) { att.getMutex().wait(25);}
+                }catch ( Exception x ) {}
         }while ( nRead == 0 && (!timedOut) );
         //else throw new IOException(sm.getString("iib.failedread"));
         return false; //timeout



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r416444 [1/2] - in /tomcat/tc6.0.x/trunk/java/org/apache: coyote/http11/Http11NioProcessor.java coyote/http11/InternalNioInputBuffer.java tomcat/util/net/NioEndpoint.java

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
basically what is happening is that the connection is "keep-alive" so it 
goes back and register itself for more read,
read return -1, which is end of stream, and it re-register itself. I 
will make it throw an exception to end the loop

Filip


Filip Hanik - Dev Lists wrote:
> Thanks for the help on this.
> I am now catching those exceptions, I have the correct speed, but 
> after the test is done, the poller is going ape-sh#@ and takes 100% of 
> cpu, making future tests really slow.
> I need to figure out why it isn't letting go of the connections
>
> Filip
>
> Remy Maucherat wrote:
>> fhanik@apache.org wrote:
>>> Author: fhanik
>>> Date: Thu Jun 22 12:05:02 2006
>>> New Revision: 416444
>>>
>>> URL: http://svn.apache.org/viewvc?rev=416444&view=rev
>>> Log:
>>> Fix so that we don't do a busy read, instead we are properly doing a 
>>> NIO poller wait
>>> This way, we can achieve blocking read, without wasting CPU cycles.
>>> Since we are using Java 5, I will be changing this implementation 
>>> from using synchronized to using the Exchanger, this is also to 
>>> avoid anyi locks that can happen. For example, in the current 
>>> implementation the poller can call notify before we have had a 
>>> chance to call wait
>>
>> This is a little bit better (2300 r/s now), but:
>> - I get some cancelled key exceptions (most likely they could be 
>> caught):
>> 22 juin 2006 21:32:38 org.apache.tomcat.util.net.NioEndpoint$Poller 
>> events
>> GRAVE:
>> java.nio.channels.CancelledKeyException
>>         at sun.nio.ch.SelectionKeyImpl.ensureValid(Unknown Source)
>>         at sun.nio.ch.SelectionKeyImpl.interestOps(Unknown Source)
>>         at 
>> org.apache.coyote.http11.InternalNioInputBuffer$1.run(InternalNioInputBuffer.java:573) 
>>
>>         at 
>> org.apache.tomcat.util.net.NioEndpoint$Poller.events(NioEndpoint.java:1120) 
>>
>>         at 
>> org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1176)
>>         at java.lang.Thread.run(Unknown Source)
>> - I get a problem in the poller thread after a while:
>> Exception in thread "http-8081-Poller-0" java.lang.NullPointerException
>>         at sun.nio.ch.WindowsSelectorImpl$FdMap.remove(Unknown Source)
>>         at sun.nio.ch.WindowsSelectorImpl$FdMap.access$3000(Unknown 
>> Source)
>>         at sun.nio.ch.WindowsSelectorImpl.implDereg(Unknown Source)
>>         at sun.nio.ch.SelectorImpl.processDeregisterQueue(Unknown 
>> Source)
>>         at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
>>         at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
>>         at sun.nio.ch.SelectorImpl.select(Unknown Source)
>>         at 
>> org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1182)
>>         at java.lang.Thread.run(Unknown Source)
>>
>> However, performance without keepalive (no -k) is down.
>>
>> Rémy
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: dev-help@tomcat.apache.org
>>
>>
>
>


-- 


Filip Hanik

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r416444 [1/2] - in /tomcat/tc6.0.x/trunk/java/org/apache: coyote/http11/Http11NioProcessor.java coyote/http11/InternalNioInputBuffer.java tomcat/util/net/NioEndpoint.java

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
Thanks for the help on this.
I am now catching those exceptions, I have the correct speed, but after 
the test is done, the poller is going ape-sh#@ and takes 100% of cpu, 
making future tests really slow.
I need to figure out why it isn't letting go of the connections

Filip

Remy Maucherat wrote:
> fhanik@apache.org wrote:
>> Author: fhanik
>> Date: Thu Jun 22 12:05:02 2006
>> New Revision: 416444
>>
>> URL: http://svn.apache.org/viewvc?rev=416444&view=rev
>> Log:
>> Fix so that we don't do a busy read, instead we are properly doing a 
>> NIO poller wait
>> This way, we can achieve blocking read, without wasting CPU cycles.
>> Since we are using Java 5, I will be changing this implementation 
>> from using synchronized to using the Exchanger, this is also to avoid 
>> anyi locks that can happen. For example, in the current 
>> implementation the poller can call notify before we have had a chance 
>> to call wait
>
> This is a little bit better (2300 r/s now), but:
> - I get some cancelled key exceptions (most likely they could be caught):
> 22 juin 2006 21:32:38 org.apache.tomcat.util.net.NioEndpoint$Poller 
> events
> GRAVE:
> java.nio.channels.CancelledKeyException
>         at sun.nio.ch.SelectionKeyImpl.ensureValid(Unknown Source)
>         at sun.nio.ch.SelectionKeyImpl.interestOps(Unknown Source)
>         at 
> org.apache.coyote.http11.InternalNioInputBuffer$1.run(InternalNioInputBuffer.java:573) 
>
>         at 
> org.apache.tomcat.util.net.NioEndpoint$Poller.events(NioEndpoint.java:1120) 
>
>         at 
> org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1176)
>         at java.lang.Thread.run(Unknown Source)
> - I get a problem in the poller thread after a while:
> Exception in thread "http-8081-Poller-0" java.lang.NullPointerException
>         at sun.nio.ch.WindowsSelectorImpl$FdMap.remove(Unknown Source)
>         at sun.nio.ch.WindowsSelectorImpl$FdMap.access$3000(Unknown 
> Source)
>         at sun.nio.ch.WindowsSelectorImpl.implDereg(Unknown Source)
>         at sun.nio.ch.SelectorImpl.processDeregisterQueue(Unknown Source)
>         at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
>         at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
>         at sun.nio.ch.SelectorImpl.select(Unknown Source)
>         at 
> org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1182)
>         at java.lang.Thread.run(Unknown Source)
>
> However, performance without keepalive (no -k) is down.
>
> Rémy
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>


-- 


Filip Hanik

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r416444 [1/2] - in /tomcat/tc6.0.x/trunk/java/org/apache: coyote/http11/Http11NioProcessor.java coyote/http11/InternalNioInputBuffer.java tomcat/util/net/NioEndpoint.java

Posted by Remy Maucherat <re...@apache.org>.
fhanik@apache.org wrote:
> Author: fhanik
> Date: Thu Jun 22 12:05:02 2006
> New Revision: 416444
> 
> URL: http://svn.apache.org/viewvc?rev=416444&view=rev
> Log:
> Fix so that we don't do a busy read, instead we are properly doing a NIO poller wait
> This way, we can achieve blocking read, without wasting CPU cycles.
> Since we are using Java 5, I will be changing this implementation from using synchronized to using the Exchanger, this is also to avoid anyi locks that can happen. For example, in the current implementation the poller can call notify before we have had a chance to call wait

This is a little bit better (2300 r/s now), but:
- I get some cancelled key exceptions (most likely they could be caught):
22 juin 2006 21:32:38 org.apache.tomcat.util.net.NioEndpoint$Poller events
GRAVE:
java.nio.channels.CancelledKeyException
         at sun.nio.ch.SelectionKeyImpl.ensureValid(Unknown Source)
         at sun.nio.ch.SelectionKeyImpl.interestOps(Unknown Source)
         at 
org.apache.coyote.http11.InternalNioInputBuffer$1.run(InternalNioInputBuffer.java:573)
         at 
org.apache.tomcat.util.net.NioEndpoint$Poller.events(NioEndpoint.java:1120)
         at 
org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1176)
         at java.lang.Thread.run(Unknown Source)
- I get a problem in the poller thread after a while:
Exception in thread "http-8081-Poller-0" java.lang.NullPointerException
         at sun.nio.ch.WindowsSelectorImpl$FdMap.remove(Unknown Source)
         at sun.nio.ch.WindowsSelectorImpl$FdMap.access$3000(Unknown Source)
         at sun.nio.ch.WindowsSelectorImpl.implDereg(Unknown Source)
         at sun.nio.ch.SelectorImpl.processDeregisterQueue(Unknown Source)
         at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
         at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
         at sun.nio.ch.SelectorImpl.select(Unknown Source)
         at 
org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1182)
         at java.lang.Thread.run(Unknown Source)

However, performance without keepalive (no -k) is down.

Rémy

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org