Tomcat源码学习--servlet请求处理

当前tomcat 8.5.20中已经不再使用bio模型,默认支持NIO实现的org.apache.coyote.http11.Http11NioProtocol,当前tomcat支持的io模型如下:

 Tomcat源码学习--servlet请求处理_第1张图片

在Tomcat启动时会启用一个端口来监听请求,并且会启动多个线程来处理相关的请求操作,如下图:

Tomcat源码学习--servlet请求处理_第2张图片

相关线程介绍:

(1)http-nio-8080-Acceptor为请求接收器,其只接收请求,不会对请求做任务业务处理操作,所以默认为单个线程。

(2)http-nio-8080-ClientPoller-0http-nio-8080-ClientPoller-1为两个是作为轮询器或者转发器使用的,简单来说就是对获取到的SocketWrapper添加到一个线程池中进行处理,这种类型的线程数与CPU的核数有关。

(3)http-nio-8080-exec-110tomcat的一个线程池产生的默认的10线程,这10个线程是用来执行具体的servlet请求操作,线程的数目可以跟随请求说的变化而变化。

以上3种类型的线程有点类似Reactor模式。

接下来我们看看tomcat是如何处理一个Servlet请求的。

1tomcat启动时会初始化一个http-nio-8080-Acceptor线程来接收请求

[java]  view plain  copy
  1. protected class Acceptor extends AbstractEndpoint.Acceptor {  
  2.   
  3.         @Override  
  4.         public void run() {  
  5.   
  6.             int errorDelay = 0;  
  7.   
  8.             while (running) {  
  9.   
  10.                 // Loop if endpoint is paused  
  11.                 while (paused && running) {  
  12.                     state = AcceptorState.PAUSED;  
  13.                     try {  
  14.                         Thread.sleep(50);  
  15.                     } catch (InterruptedException e) {  
  16.                         // Ignore  
  17.                     }  
  18.                 }  
  19.   
  20.                 if (!running) {  
  21.                     break;  
  22.                 }  
  23.                 state = AcceptorState.RUNNING;  
  24.   
  25.                 try {  
  26.                     countUpOrAwaitConnection();  
  27.   
  28.                     SocketChannel socket = null;  
  29.                     try {  
  30.                         // Accept the next incoming connection from the server  
  31.                         // socket  
  32.             //阻塞方式等待请求  
  33.                         socket = serverSock.accept();  
  34.                     } catch (IOException ioe) {  
  35.                         // We didn't get a socket  
  36.                         countDownConnection();  
  37.                         if (running) {  
  38.                             // Introduce delay if necessary  
  39.                             errorDelay = handleExceptionWithDelay(errorDelay);  
  40.                             // re-throw  
  41.                             throw ioe;  
  42.                         } else {  
  43.                             break;  
  44.                         }  
  45.                     }  
  46.                     // Successful accept, reset the error delay  
  47.                     errorDelay = 0;  
  48.   
  49.                     // Configure the socket  
  50.                     if (running && !paused) {  
  51.                         // setSocketOptions() will hand the socket off to  
  52.                         // an appropriate processor if successful  
  53.             //对获取的请求进行处理操作  
  54.                         if (!setSocketOptions(socket)) {  
  55.                             closeSocket(socket);  
  56.                         }  
  57.                     } else {  
  58.                         closeSocket(socket);  
  59.                     }  
  60.                 } catch (Throwable t) {  
  61.                     ExceptionUtils.handleThrowable(t);  
  62.                     log.error(sm.getString("endpoint.accept.fail"), t);  
  63.                 }  
  64.             }  
  65.             state = AcceptorState.ENDED;  
  66.         }  
  67.   
  68.   
  69.         private void closeSocket(SocketChannel socket) {  
  70.             countDownConnection();  
  71.             try {  
  72.                 socket.socket().close();  
  73.             } catch (IOException ioe)  {  
  74.                 if (log.isDebugEnabled()) {  
  75.                     log.debug(sm.getString("endpoint.err.close"), ioe);  
  76.                 }  
  77.             }  
  78.             try {  
  79.                 socket.close();  
  80.             } catch (IOException ioe) {  
  81.                 if (log.isDebugEnabled()) {  
  82.                     log.debug(sm.getString("endpoint.err.close"), ioe);  
  83.                 }  
  84.             }  
  85.         }  
  86.     }  

在上面代码中, socket = serverSock.accept();与客户端建立连接,将连接的socket交给processSocket(socket)来处理,在processSocket会将socket进行包装成NioChannel交给Poller线程来进行处理。

[java]  view plain  copy
  1. protected boolean setSocketOptions(SocketChannel socket) {  
  2.         // Process the connection  
  3.         try {  
  4.             //disable blocking, APR style, we are gonna be polling it  
  5.             socket.configureBlocking(false);  
  6.             Socket sock = socket.socket();  
  7.             socketProperties.setProperties(sock);  
  8.   
  9.             NioChannel channel = nioChannels.pop();  
  10.             if (channel == null) {  
  11.                 SocketBufferHandler bufhandler = new SocketBufferHandler(  
  12.                         socketProperties.getAppReadBufSize(),  
  13.                         socketProperties.getAppWriteBufSize(),  
  14.                         socketProperties.getDirectBuffer());  
  15.                 if (isSSLEnabled()) {  
  16.                     channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);  
  17.                 } else {  
  18.                     channel = new NioChannel(socket, bufhandler);  
  19.                 }  
  20.             } else {  
  21.                 channel.setIOChannel(socket);  
  22.                 channel.reset();  
  23.             }  
  24.             //交给Poller线程进行处理操作  
  25.             getPoller0().register(channel);  
  26.         } catch (Throwable t) {  
  27.             ExceptionUtils.handleThrowable(t);  
  28.             try {  
  29.                 log.error("",t);  
  30.             } catch (Throwable tt) {  
  31.                 ExceptionUtils.handleThrowable(tt);  
  32.             }  
  33.             // Tell to close the socket  
  34.             return false;  
  35.         }  
  36.         return true;  
  37.     }  

2、tomcat根据处理器核数创建http-nio-8080-ClientPoller-0http-nio-8080-ClientPoller-1线程

Poller线程会通过while(true)不断从selector.selectdKeys获取是否有连接存在,如果有连接存在则从SelectionKey中获取NioSocketWrapper并通过processKey来进行处理

[java]  view plain  copy
  1. @Override  
  2.        public void run() {  
  3.            // Loop until destroy() is called  
  4.            while (true) {  
  5.   
  6.                boolean hasEvents = false;  
  7.   
  8.                try {  
  9.                    if (!close) {  
  10.                        hasEvents = events();  
  11.                        if (wakeupCounter.getAndSet(-1) > 0) {  
  12.                            //if we are here, means we have other stuff to do  
  13.                            //do a non blocking select  
  14.                            keyCount = selector.selectNow();  
  15.                        } else {  
  16.                            keyCount = selector.select(selectorTimeout);  
  17.                        }  
  18.                        wakeupCounter.set(0);  
  19.                    }  
  20.                    if (close) {  
  21.                        events();  
  22.                        timeout(0false);  
  23.                        try {  
  24.                            selector.close();  
  25.                        } catch (IOException ioe) {  
  26.                            log.error(sm.getString("endpoint.nio.selectorCloseFail"), ioe);  
  27.                        }  
  28.                        break;  
  29.                    }  
  30.                } catch (Throwable x) {  
  31.                    ExceptionUtils.handleThrowable(x);  
  32.                    log.error("",x);  
  33.                    continue;  
  34.                }  
  35.                //either we timed out or we woke up, process events first  
  36.                if ( keyCount == 0 ) hasEvents = (hasEvents | events());  
  37.   
  38.                Iterator iterator =  
  39.                    keyCount > 0 ? selector.selectedKeys().iterator() : null;  
  40.                // Walk through the collection of ready keys and dispatch  
  41.                // any active event.  
  42.                while (iterator != null && iterator.hasNext()) {  
  43.                    SelectionKey sk = iterator.next();  
  44.                    NioSocketWrapper attachment = (NioSocketWrapper)sk.attachment();  
  45.                    // Attachment may be null if another thread has called  
  46.                    // cancelledKey()  
  47.                    if (attachment == null) {  
  48.                        iterator.remove();  
  49.                    } else {  
  50.                        iterator.remove();  
  51.                     //获取到的请求NioSocketWrapper  
  52.                        processKey(sk, attachment);  
  53.                    }  
  54.                }//while  
  55.   
  56.                //process timeouts  
  57.                timeout(keyCount,hasEvents);  
  58.            }//while  
  59.   
  60.            getStopLatch().countDown();  
  61.        }  

processKey中会判断一些SelectionKeyd 的状态,并将NioSocketWrapper提交给processSocket(SocketWrapperBase socketWrapper,

            SocketEvent event, boolean dispatch)来进行处理。

[java]  view plain  copy
  1. public boolean processSocket(SocketWrapperBase socketWrapper,  
  2.             SocketEvent event, boolean dispatch) {  
  3.         try {  
  4.             if (socketWrapper == null) {  
  5.                 return false;  
  6.             }  
  7.             SocketProcessorBase sc = processorCache.pop();  
  8.             if (sc == null) {  
  9.                 sc = createSocketProcessor(socketWrapper, event);  
  10.             } else {  
  11.                 sc.reset(socketWrapper, event);  
  12.             }  
  13.             //获取线程池,提交请求到线程池中进行处理  
  14.             Executor executor = getExecutor();  
  15.             if (dispatch && executor != null) {  
  16.                 executor.execute(sc);  
  17.             } else {  
  18.                 sc.run();  
  19.             }  
  20.         } catch (RejectedExecutionException ree) {  
  21.             getLog().warn(sm.getString("endpoint.executor.fail", socketWrapper) , ree);  
  22.             return false;  
  23.         } catch (Throwable t) {  
  24.             ExceptionUtils.handleThrowable(t);  
  25.             // This means we got an OOM or similar creating a thread, or that  
  26.             // the pool and its queue are full  
  27.             getLog().error(sm.getString("endpoint.process.fail"), t);  
  28.             return false;  
  29.         }  
  30.         return true;  
  31.     }  

processSocket函数中会获取请求处理线程,将SocketProcessor提交到线程池中进行请求处理操作。

2、tomcat创建线程池来处理所有的servlet请求,线程池中线程名称为http-nio-8080-exec-110,用来对具体的请求进行处理操作,NIO对应的线程操作类为SocketProcessor

socketProcessor线程运行时会调用doRun()方法,在doRun()方法中调用getHandler().process(socketWrapper, SocketEvent.OPEN_READ)来处理socketWrapper请求

[java]  view plain  copy
  1. protected class SocketProcessor extends SocketProcessorBase {  
  2.   
  3.        public SocketProcessor(SocketWrapperBase socketWrapper, SocketEvent event) {  
  4.            super(socketWrapper, event);  
  5.        }  
  6.   
  7.        @Override  
  8.        protected void doRun() {  
  9.            NioChannel socket = socketWrapper.getSocket();  
  10.            SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());  
  11.   
  12.            try {  
  13.                int handshake = -1;  
  14.   
  15.                try {  
  16.                    if (key != null) {  
  17.                        if (socket.isHandshakeComplete()) {  
  18.                             
  19.                            handshake = 0;  
  20.                        } else if (event == SocketEvent.STOP || event == SocketEvent.DISCONNECT ||  
  21.                                event == SocketEvent.ERROR) {  
  22.                            handshake = -1;  
  23.                        } else {  
  24.                            handshake = socket.handshake(key.isReadable(), key.isWritable());  
  25.                             
  26.                            event = SocketEvent.OPEN_READ;  
  27.                        }  
  28.                    }  
  29.                } catch (IOException x) {  
  30.                    handshake = -1;  
  31.                    if (log.isDebugEnabled()) log.debug("Error during SSL handshake",x);  
  32.                } catch (CancelledKeyException ckx) {  
  33.                    handshake = -1;  
  34.                }  
  35.                if (handshake == 0) {  
  36.                    SocketState state = SocketState.OPEN;  
  37.                    // Process the request from this socket  
  38.                 //获取处理器调用process操作  
  39.                    if (event == null) {  
  40.                        state = getHandler().process(socketWrapper, SocketEvent.OPEN_READ);  
  41.                    } else {  
  42.                        state = getHandler().process(socketWrapper, event);  
  43.                    }  
  44.                    if (state == SocketState.CLOSED) {  
  45.                        close(socket, key);  
  46.                    }  
  47.                } else if (handshake == -1 ) {  
  48.                    close(socket, key);  
  49.                } else if (handshake == SelectionKey.OP_READ){  
  50.                    socketWrapper.registerReadInterest();  
  51.                } else if (handshake == SelectionKey.OP_WRITE){  
  52.                    socketWrapper.registerWriteInterest();  
  53.                }  
  54.            } catch (CancelledKeyException cx) {  
  55.                socket.getPoller().cancelledKey(key);  
  56.            } catch (VirtualMachineError vme) {  
  57.                ExceptionUtils.handleThrowable(vme);  
  58.            } catch (Throwable t) {  
  59.                log.error("", t);  
  60.                socket.getPoller().cancelledKey(key);  
  61.            } finally {  
  62.                socketWrapper = null;  
  63.                event = null;  
  64.                //return to cache  
  65.                if (running && !paused) {  
  66.                    processorCache.push(this);  
  67.                }  
  68.            }  
  69.        }  
  70.    }  

在父类AbstractProtocolprocess方法中会获取处理器Processor,在处理器Processor.process(SocketWrapperBase socketWrapper, SocketEvent status)中调用service方法处理socketWrapper

[java]  view plain  copy
  1. @Override  
  2.    public SocketState process(SocketWrapperBase socketWrapper, SocketEvent status)  
  3.            throws IOException {  
  4.   
  5.        SocketState state = SocketState.CLOSED;  
  6.        Iterator dispatches = null;  
  7.        do {  
  8.            if (dispatches != null) {  
  9.                DispatchType nextDispatch = dispatches.next();  
  10.                state = dispatch(nextDispatch.getSocketStatus());  
  11.            } else if (status == SocketEvent.DISCONNECT) {  
  12.                // Do nothing here, just wait for it to get recycled  
  13.            } else if (isAsync() || isUpgrade() || state == SocketState.ASYNC_END) {  
  14.                state = dispatch(status);  
  15.                if (state == SocketState.OPEN) {  
  16.                    // There may be pipe-lined data to read. If the data isn't  
  17.                    // processed now, execution will exit this loop and call  
  18.                    // release() which will recycle the processor (and input  
  19.                    // buffer) deleting any pipe-lined data. To avoid this,  
  20.                    // process it now.  
  21.                 //调用service方法处理SocketWrapper  
  22.                    state = service(socketWrapper);  
  23.                }  
  24.            } else if (status == SocketEvent.OPEN_WRITE) {  
  25.                // Extra write event likely after async, ignore  
  26.                state = SocketState.LONG;  
  27.            } else if (status == SocketEvent.OPEN_READ){  
  28.                state = service(socketWrapper);  
  29.            } else {  
  30.                // Default to closing the socket if the SocketEvent passed in  
  31.                // is not consistent with the current state of the Processor  
  32.                state = SocketState.CLOSED;  
  33.            }  
  34.   
  35.            if (state != SocketState.CLOSED && isAsync()) {  
  36.                state = asyncPostProcess();  
  37.            }  
  38.   
  39.            if (getLog().isDebugEnabled()) {  
  40.                getLog().debug("Socket: [" + socketWrapper +  
  41.                        "], Status in: [" + status +  
  42.                        "], State out: [" + state + "]");  
  43.            }  
  44.   
  45.            if (dispatches == null || !dispatches.hasNext()) {  
  46.                // Only returns non-null iterator if there are  
  47.                // dispatches to process.  
  48.                dispatches = getIteratorAndClearDispatches();  
  49.            }  
  50.        } while (state == SocketState.ASYNC_END ||  
  51.                dispatches != null && state != SocketState.CLOSED);  
  52.   
  53.        return state;  
  54.    }  

在http11Processor中调用service(socketWrapper)进行处理操作,调用CoyoteAdapter的service(request,response)方法进行请求操作。

[java]  view plain  copy
  1. @Override  
  2.     public SocketState service(SocketWrapperBase socketWrapper)  
  3.         throws IOException {  
  4.         RequestInfo rp = request.getRequestProcessor();  
  5.         rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);  
  6.   
  7.         // Setting up the I/O  
  8.         setSocketWrapper(socketWrapper);  
  9.         inputBuffer.init(socketWrapper);  
  10.         outputBuffer.init(socketWrapper);  
  11.   
  12.         // Flags  
  13.         keepAlive = true;  
  14.         openSocket = false;  
  15.         readComplete = true;  
  16.         boolean keptAlive = false;  
  17.         SendfileState sendfileState = SendfileState.DONE;  
  18.   
  19.         while (!getErrorState().isError() && keepAlive && !isAsync() && upgradeToken == null &&  
  20.                 sendfileState == SendfileState.DONE && !endpoint.isPaused()) {  
  21.   
  22.             // Parsing the request header  
  23.             try {  
  24.                 if (!inputBuffer.parseRequestLine(keptAlive)) {  
  25.                     if (inputBuffer.getParsingRequestLinePhase() == -1) {  
  26.                         return SocketState.UPGRADING;  
  27.                     } else if (handleIncompleteRequestLineRead()) {  
  28.                         break;  
  29.                     }  
  30.                 }  
  31.   
  32.                 if (endpoint.isPaused()) {  
  33.                     // 503 - Service unavailable  
  34.                     response.setStatus(503);  
  35.                     setErrorState(ErrorState.CLOSE_CLEAN, null);  
  36.                 } else {  
  37.                     keptAlive = true;  
  38.                     // Set this every time in case limit has been changed via JMX  
  39.                     request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());  
  40.                     if (!inputBuffer.parseHeaders()) {  
  41.                         // We've read part of the request, don't recycle it  
  42.                         // instead associate it with the socket  
  43.                         openSocket = true;  
  44.                         readComplete = false;  
  45.                         break;  
  46.                     }  
  47.                     if (!disableUploadTimeout) {  
  48.                         socketWrapper.setReadTimeout(connectionUploadTimeout);  
  49.                     }  
  50.                 }  
  51.             } catch (IOException e) {  
  52.                 if (log.isDebugEnabled()) {  
  53.                     log.debug(sm.getString("http11processor.header.parse"), e);  
  54.                 }  
  55.                 setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);  
  56.                 break;  
  57.             } catch (Throwable t) {  
  58.                 ExceptionUtils.handleThrowable(t);  
  59.                 UserDataHelper.Mode logMode = userDataHelper.getNextMode();  
  60.                 if (logMode != null) {  
  61.                     String message = sm.getString("http11processor.header.parse");  
  62.                     switch (logMode) {  
  63.                         case INFO_THEN_DEBUG:  
  64.                             message += sm.getString("http11processor.fallToDebug");  
  65.                             //$FALL-THROUGH$  
  66.                         case INFO:  
  67.                             log.info(message, t);  
  68.                             break;  
  69.                         case DEBUG:  
  70.                             log.debug(message, t);  
  71.                     }  
  72.                 }  
  73.                 // 400 - Bad Request  
  74.                 response.setStatus(400);  
  75.                 setErrorState(ErrorState.CLOSE_CLEAN, t);  
  76.                 getAdapter().log(request, response, 0);  
  77.             }  
  78.   
  79.             // Has an upgrade been requested?  
  80.             Enumeration connectionValues = request.getMimeHeaders().values("Connection");  
  81.             boolean foundUpgrade = false;  
  82.             while (connectionValues.hasMoreElements() && !foundUpgrade) {  
  83.                 foundUpgrade = connectionValues.nextElement().toLowerCase(  
  84.                         Locale.ENGLISH).contains("upgrade");  
  85.             }  
  86.   
  87.             if (foundUpgrade) {  
  88.                 // Check the protocol  
  89.                 String requestedProtocol = request.getHeader("Upgrade");  
  90.   
  91.                 UpgradeProtocol upgradeProtocol = httpUpgradeProtocols.get(requestedProtocol);  
  92.                 if (upgradeProtocol != null) {  
  93.                     if (upgradeProtocol.accept(request)) {  
  94.                         // TODO Figure out how to handle request bodies at this  
  95.                         // point.  
  96.                         response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS);  
  97.                         response.setHeader("Connection""Upgrade");  
  98.                         response.setHeader("Upgrade", requestedProtocol);  
  99.                         action(ActionCode.CLOSE,  null);  
  100.                         getAdapter().log(request, response, 0);  
  101.   
  102.                         InternalHttpUpgradeHandler upgradeHandler =  
  103.                                 upgradeProtocol.getInternalUpgradeHandler(  
  104.                                         getAdapter(), cloneRequest(request));  
  105.                         UpgradeToken upgradeToken = new UpgradeToken(upgradeHandler, nullnull);  
  106.                         action(ActionCode.UPGRADE, upgradeToken);  
  107.                         return SocketState.UPGRADING;  
  108.                     }  
  109.                 }  
  110.             }  
  111.   
  112.             if (!getErrorState().isError()) {  
  113.                 // Setting up filters, and parse some request headers  
  114.                 rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);  
  115.                 try {  
  116.                     prepareRequest();  
  117.                 } catch (Throwable t) {  
  118.                     ExceptionUtils.handleThrowable(t);  
  119.                     if (log.isDebugEnabled()) {  
  120.                         log.debug(sm.getString("http11processor.request.prepare"), t);  
  121.                     }  
  122.                     // 500 - Internal Server Error  
  123.                     response.setStatus(500);  
  124.                     setErrorState(ErrorState.CLOSE_CLEAN, t);  
  125.                     getAdapter().log(request, response, 0);  
  126.                 }  
  127.             }  
  128.   
  129.             if (maxKeepAliveRequests == 1) {  
  130.                 keepAlive = false;  
  131.             } else if (maxKeepAliveRequests > 0 &&  
  132.                     socketWrapper.decrementKeepAlive() <= 0) {  
  133.                 keepAlive = false;  
  134.             }  
  135.   
  136.             // Process the request in the adapter  
  137.             if (!getErrorState().isError()) {  
  138.                 try {  
  139.                     rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);  
  140.                     getAdapter().service(request, response);  
  141.                     // Handle when the response was committed before a serious  
  142.                     // error occurred.  Throwing a ServletException should both  
  143.                     // set the status to 500 and set the errorException.  
  144.                     // If we fail here, then the response is likely already  
  145.                     // committed, so we can't try and set headers.  
  146.                     if(keepAlive && !getErrorState().isError() && !isAsync() &&  
  147.                             statusDropsConnection(response.getStatus())) {  
  148.                         setErrorState(ErrorState.CLOSE_CLEAN, null);  
  149.                     }  
  150.                 } catch (InterruptedIOException e) {  
  151.                     setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);  
  152.                 } catch (HeadersTooLargeException e) {  
  153.                     log.error(sm.getString("http11processor.request.process"), e);  
  154.                     // The response should not have been committed but check it  
  155.                     // anyway to be safe  
  156.                     if (response.isCommitted()) {  
  157.                         setErrorState(ErrorState.CLOSE_NOW, e);  
  158.                     } else {  
  159.                         response.reset();  
  160.                         response.setStatus(500);  
  161.                         setErrorState(ErrorState.CLOSE_CLEAN, e);  
  162.                         response.setHeader("Connection""close"); // TODO: Remove  
  163.                     }  
  164.                 } catch (Throwable t) {  
  165.                     ExceptionUtils.handleThrowable(t);  
  166.                     log.error(sm.getString("http11processor.request.process"), t);  
  167.                     // 500 - Internal Server Error  
  168.                     response.setStatus(500);  
  169.                     setErrorState(ErrorState.CLOSE_CLEAN, t);  
  170.                     getAdapter().log(request, response, 0);  
  171.                 }  
  172.             }  
  173.   
  174.             // Finish the handling of the request  
  175.             rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);  
  176.             if (!isAsync()) {  
  177.                 // If this is an async request then the request ends when it has  
  178.                 // been completed. The AsyncContext is responsible for calling  
  179.                 // endRequest() in that case.  
  180.                 endRequest();  
  181.             }  
  182.             rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);  
  183.   
  184.             // If there was an error, make sure the request is counted as  
  185.             // and error, and update the statistics counter  
  186.             if (getErrorState().isError()) {  
  187.                 response.setStatus(500);  
  188.             }  
  189.   
  190.             if (!isAsync() || getErrorState().isError()) {  
  191.                 request.updateCounters();  
  192.                 if (getErrorState().isIoAllowed()) {  
  193.                     inputBuffer.nextRequest();  
  194.                     outputBuffer.nextRequest();  
  195.                 }  
  196.             }  
  197.   
  198.             if (!disableUploadTimeout) {  
  199.                 int soTimeout = endpoint.getConnectionTimeout();  
  200.                 if(soTimeout > 0) {  
  201.                     socketWrapper.setReadTimeout(soTimeout);  
  202.                 } else {  
  203.                     socketWrapper.setReadTimeout(0);  
  204.                 }  
  205.             }  
  206.   
  207.             rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);  
  208.   
  209.             sendfileState = processSendfile(socketWrapper);  
  210.         }  
  211.   
  212.         rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);  
  213.   
  214.         if (getErrorState().isError() || endpoint.isPaused()) {  
  215.             return SocketState.CLOSED;  
  216.         } else if (isAsync()) {  
  217.             return SocketState.LONG;  
  218.         } else if (isUpgrade()) {  
  219.             return SocketState.UPGRADING;  
  220.         } else {  
  221.             if (sendfileState == SendfileState.PENDING) {  
  222.                 return SocketState.SENDFILE;  
  223.             } else {  
  224.                 if (openSocket) {  
  225.                     if (readComplete) {  
  226.                         return SocketState.OPEN;  
  227.                     } else {  
  228.                         return SocketState.LONG;  
  229.                     }  
  230.                 } else {  
  231.                     return SocketState.CLOSED;  
  232.                 }  
  233.             }  
  234.         }  
  235.     }  

你可能感兴趣的:(Tomcat源码学习--servlet请求处理)