Author: fhanik
Date: Tue May 29 14:53:52 2007
New Revision: 542666

URL: http://svn.apache.org/viewvc?view=rev&rev=542666
Log:
implement non blocking reading of the request line

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

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?view=diff&rev=542666&r1=542665&r2=542666
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Tue May 
29 14:53:52 2007
@@ -792,14 +792,6 @@
         RequestInfo rp = request.getRequestProcessor();
         rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
 
-        // Set the remote address
-        remoteAddr = null;
-        remoteHost = null;
-        localAddr = null;
-        localName = null;
-        remotePort = -1;
-        localPort = -1;
-
         // Setting up the socket
         this.socket = socket;
         inputBuffer.setSocket(socket);
@@ -829,17 +821,17 @@
                     
socket.getIOChannel().socket().setSoTimeout((int)soTimeout);
                     inputBuffer.readTimeout = soTimeout;
                 }
-                if (!inputBuffer.parseRequestLine(keptAlive && 
(endpoint.getCurrentThreadsBusy() >= limit))) {
-                    // This means that no data is available right now
-                    // (long keepalive), so that the processor should be 
recycled
-                    // and the method should return true
+                if (!inputBuffer.parseRequestLine(keptAlive)) {
+                    //no data available yet, since we might have read part
+                    //of the request line, we can't recycle the processor
                     openSocket = true;
-                    // Add the socket to the poller
-                    socket.getPoller().add(socket);
+                    recycle = false;
                     break;
                 }
                 keptAlive = true;
                 if ( !inputBuffer.parseHeaders() ) {
+                    //we've read part of the request, don't recycle it
+                    //instead associate it with the socket
                     openSocket = true;
                     recycle = false;
                     break;
@@ -992,6 +984,12 @@
         this.socket = null;
         this.cometClose = false;
         this.comet = false;
+        remoteAddr = null;
+        remoteHost = null;
+        localAddr = null;
+        localName = null;
+        remotePort = -1;
+        localPort = -1;
     }
 
 

Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?view=diff&rev=542666&r1=542665&r2=542666
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Tue 
May 29 14:53:52 2007
@@ -72,6 +72,9 @@
 
         parsingHeader = true;
         parsingRequestLine = true;
+        parsingRequestLinePhase = 0;
+        parsingRequestLineEol = false;
+        parsingRequestLineStart = 0;
         headerParsePos = HeaderParsePosition.HEADER_START;
         headerData.recycle();
         swallowInput = true;
@@ -115,6 +118,9 @@
      */
     protected boolean parsingHeader;
     protected boolean parsingRequestLine;
+    protected int parsingRequestLinePhase = 0;
+    protected boolean parsingRequestLineEol = false;
+    protected int parsingRequestLineStart = 0;
     protected HeaderParsePosition headerParsePos;
 
 
@@ -305,6 +311,9 @@
         parsingHeader = true;
         headerParsePos = HeaderParsePosition.HEADER_START;
         parsingRequestLine = true;
+        parsingRequestLinePhase = 0;
+        parsingRequestLineEol = false;
+        parsingRequestLineStart = 0;
         headerData.recycle();
         swallowInput = true;
 
@@ -346,6 +355,9 @@
         parsingHeader = true;
         headerParsePos = HeaderParsePosition.HEADER_START;
         parsingRequestLine = true;
+        parsingRequestLinePhase = 0;
+        parsingRequestLineEol = false;
+        parsingRequestLineStart = 0;
         headerData.recycle();
         swallowInput = true;
 
@@ -384,160 +396,148 @@
 
         //check state
         if ( !parsingRequestLine ) return true;
-        
-        int start = 0;
-
         //
         // Skipping blank lines
         //
-
-        byte chr = 0;
-        do {
-
-            // Read new bytes if needed
+        if ( parsingRequestLinePhase == 0 ) {
+            byte chr = 0;
+            do {
+                
+                // Read new bytes if needed
+                if (pos >= lastValid) {
+                    if (useAvailableData) {
+                        return false;
+                    }
+                    if (readTimeout == -1) {
+                        if (!fill(false,true)) //request line parsing
+                            throw new 
EOFException(sm.getString("iib.eof.error"));
+                    } else {
+                        // Do a simple read with a short timeout
+                        if ( !readSocket(true, false) ) return false;
+                    }
+                }
+                chr = buf[pos++];
+            } while ((chr == Constants.CR) || (chr == Constants.LF));
+            pos--;
+            parsingRequestLineStart = pos;
+            parsingRequestLinePhase = 1;
+        } 
+        if ( parsingRequestLinePhase == 1 ) {
+            // Mark the current buffer position
+            
             if (pos >= lastValid) {
                 if (useAvailableData) {
                     return false;
                 }
                 if (readTimeout == -1) {
-                    if (!fill(false,true)) //request line parsing
-                        throw new EOFException(sm.getString("iib.eof.error"));
+                    if (!fill(false,false)) //request line parsing
+                        return false;
                 } else {
                     // Do a simple read with a short timeout
                     if ( !readSocket(true, false) ) return false;
                 }
             }
-
-            chr = buf[pos++];
-
-        } while ((chr == Constants.CR) || (chr == Constants.LF));
-
-        pos--;
-
-        // Mark the current buffer position
-        start = pos;
-
-        if (pos >= lastValid) {
-            if (useAvailableData) {
-                return false;
-            }
-            if (readTimeout == -1) {
-                if (!fill(false,false)) //request line parsing
-                    return false;
-            } else {
-                // Do a simple read with a short timeout
-                if ( !readSocket(true, false) ) return false;
-            }
+            parsingRequestLinePhase = 2;
         }
-
-        //
-        // Reading the method name
-        // Method name is always US-ASCII
-        //
-
-        boolean space = false;
-
-        while (!space) {
-
-            // Read new bytes if needed
-            if (pos >= lastValid) {
-                if (!fill(true,false)) //request line parsing
-                    return false;
-            }
-
-            if (buf[pos] == Constants.SP) {
-                space = true;
-                request.method().setBytes(buf, start, pos - start);
+        if ( parsingRequestLinePhase == 2 ) {
+            //
+            // Reading the method name
+            // Method name is always US-ASCII
+            //
+            boolean space = false;
+            while (!space) {
+                // Read new bytes if needed
+                if (pos >= lastValid) {
+                    if (!fill(true, false)) //request line parsing
+                        return false;
+                }
+                if (buf[pos] == Constants.SP) {
+                    space = true;
+                    request.method().setBytes(buf, parsingRequestLineStart, 
pos - parsingRequestLineStart);
+                }
+                pos++;
             }
-
-            pos++;
-
+            parsingRequestLineStart = pos;
+            parsingRequestLinePhase = 3;
         }
-
-        // Mark the current buffer position
-        start = pos;
-        int end = 0;
-        int questionPos = -1;
-
-        //
-        // Reading the URI
-        //
-
-        space = false;
-        boolean eol = false;
-
-        while (!space) {
-
-            // Read new bytes if needed
-            if (pos >= lastValid) {
-                if (!fill(true,false)) //request line parsing
-                    return false;
+        if ( parsingRequestLinePhase == 3 ) {
+            // Mark the current buffer position
+            
+            int end = 0;
+            int questionPos = -1;
+            //
+            // Reading the URI
+            //
+            boolean space = false;
+            while (!space) {
+                // Read new bytes if needed
+                if (pos >= lastValid) {
+                    if (!fill(true,false)) //request line parsing
+                        return false;
+                }
+                if (buf[pos] == Constants.SP) {
+                    space = true;
+                    end = pos;
+                } else if ((buf[pos] == Constants.CR) 
+                           || (buf[pos] == Constants.LF)) {
+                    // HTTP/0.9 style request
+                    parsingRequestLineEol = true;
+                    space = true;
+                    end = pos;
+                } else if ((buf[pos] == Constants.QUESTION) 
+                           && (questionPos == -1)) {
+                    questionPos = pos;
+                }
+                pos++;
             }
-
-            if (buf[pos] == Constants.SP) {
-                space = true;
-                end = pos;
-            } else if ((buf[pos] == Constants.CR) 
-                       || (buf[pos] == Constants.LF)) {
-                // HTTP/0.9 style request
-                eol = true;
-                space = true;
-                end = pos;
-            } else if ((buf[pos] == Constants.QUESTION) 
-                       && (questionPos == -1)) {
-                questionPos = pos;
+            request.unparsedURI().setBytes(buf, parsingRequestLineStart, end - 
parsingRequestLineStart);
+            if (questionPos >= 0) {
+                request.queryString().setBytes(buf, questionPos + 1, 
+                                               end - questionPos - 1);
+                request.requestURI().setBytes(buf, parsingRequestLineStart, 
questionPos - parsingRequestLineStart);
+            } else {
+                request.requestURI().setBytes(buf, parsingRequestLineStart, 
end - parsingRequestLineStart);
             }
-
-            pos++;
-
+            parsingRequestLineStart = pos;
+            parsingRequestLinePhase = 4;
         }
-
-        request.unparsedURI().setBytes(buf, start, end - start);
-        if (questionPos >= 0) {
-            request.queryString().setBytes(buf, questionPos + 1, 
-                                           end - questionPos - 1);
-            request.requestURI().setBytes(buf, start, questionPos - start);
-        } else {
-            request.requestURI().setBytes(buf, start, end - start);
-        }
-
-        // Mark the current buffer position
-        start = pos;
-        end = 0;
-
-        //
-        // Reading the protocol
-        // Protocol is always US-ASCII
-        //
-
-        while (!eol) {
-
-            // Read new bytes if needed
-            if (pos >= lastValid) {
-                if (!fill(true,false)) //reques line parsing
-                    return false;
-            }
-
-            if (buf[pos] == Constants.CR) {
-                end = pos;
-            } else if (buf[pos] == Constants.LF) {
-                if (end == 0)
+        if ( parsingRequestLinePhase == 4 ) {
+            // Mark the current buffer position
+            
+            end = 0;
+            //
+            // Reading the protocol
+            // Protocol is always US-ASCII
+            //
+            while (!parsingRequestLineEol) {
+                // Read new bytes if needed
+                if (pos >= lastValid) {
+                    if (!fill(true, false)) //reques line parsing
+                        return false;
+                }
+        
+                if (buf[pos] == Constants.CR) {
                     end = pos;
-                eol = true;
+                } else if (buf[pos] == Constants.LF) {
+                    if (end == 0)
+                        end = pos;
+                    parsingRequestLineEol = true;
+                }
+                pos++;
             }
-
-            pos++;
-
-        }
-
-        if ((end - start) > 0) {
-            request.protocol().setBytes(buf, start, end - start);
-        } else {
-            request.protocol().setString("");
+        
+            if ( (end - parsingRequestLineStart) > 0) {
+                request.protocol().setBytes(buf, parsingRequestLineStart, end 
- parsingRequestLineStart);
+            } else {
+                request.protocol().setString("");
+            }
+            parsingRequestLine = false;
+            parsingRequestLinePhase = 0;
+            parsingRequestLineEol = false;
+            parsingRequestLineStart = 0;
+            return true;
         }
-        parsingRequestLine = false;
-        return true;
-
+        throw new IllegalStateException("Invalid request line parse 
phase:"+parsingRequestLinePhase);
     }
     
     private void expand(int newsize) {

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?view=diff&rev=542666&r1=542665&r2=542666
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Tue May 29 
14:53:52 2007
@@ -1461,6 +1461,7 @@
                     while (iterator != null && iterator.hasNext()) {
                         SelectionKey sk = (SelectionKey) iterator.next();
                         KeyAttachment attachment = 
(KeyAttachment)sk.attachment();
+                        attachment.access();
                         iterator.remove();
                         processKey(sk, attachment);
                     }//while



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to