https://issues.apache.org/bugzilla/show_bug.cgi?id=54315
Konstantin Kolinko <knst.koli...@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|INVALID |--- --- Comment #12 from Konstantin Kolinko <knst.koli...@gmail.com> --- Lorenzo's thread on users@ for Tomcat 7.0.50: http://marc.info/?t=139351186000004&r=1&w=2 Just some guesses 1. This should not happen, because StandardWrapperValve.invoke() takes care of it. If web application is being stopped while some requests are still being processed, Tomcat logs the following message is logged like the following: [[[ 05-Mar-2014 19:59:33.701 INFO [localhost-startStop-1] org.apache.catalina.core.StandardWrapper.unload Waiting for 1 instance(s) to be deallocated for Servlet [jsp] 05-Mar-2014 19:59:34.701 INFO [localhost-startStop-1] org.apache.catalina.core.StandardWrapper.unload Waiting for 1 instance(s) to be deallocated for Servlet [jsp] ]]] If such errors are logged, it is explainable that other errors may follow. Note though that the messages are logged at INFO level. Sometimes logs are configured to skip those. Note that 1) StandardContext.stopInternal() stops its wrappers (=children) before all other subcomponents 2) The issue is reported as occurring in a filter. Invoking the filter chain is performed in StandardWrapperValve.invoke() in between wrapper.allocate() and wrapper.deallocate() calls. As such, it should be protected by the same allocation counter that protects the servlet that is being called here. 2. In StandardWrapper.allocate() I think the following code: [[[ if (unloading) throw new ServletException (sm.getString("standardWrapper.unloading", getName())); ]]] would better be copied inside synchronized (this) {} block below. The 'unloading' field may change while we are waiting to get into synchronized block. That is if there is the following sequence of events: TH1: in StandardWrapper.allocate() checks for unloading TH1: in StandardWrapper.allocate() waits for synchronized block TH2: executes StandardWrapper.unload() TH1: in StandardWrapper.allocate() obtains the monitor and allocates a servlet Expected: TH1 should not be able to allocate one, as unloading has already happened. 3. I think the o.a.c.core.StandardContext.paused field would better be marked volatile. The redeployment happens in background thread, but the field is read in CoyoteAdapter.postParseRequest() in a request processing thread. It might read a stale value. (It would not cause this NullPointerException as reported here. It can cause "503 Unavailable" response from StandardWrapperValve.invoke() or ServletException("standardWrapper.unloading") from StandardWrapper.allocate()). 4. In StandardWrapper.invoke() the check for "if (!context.getState().isAvailable())" is done before "wrapper.allocate()" call. There is small time window between those checks. (It would not cause this NullPointerException as reported here. It can cause ServletException("standardWrapper.unloading") from StandardWrapper.allocate()). Anyway, in this case I do not see how it could be done better. The LifecycleBase.state field is already marked as 'volatile'. Asking for it twice seems like a waste. The checks in allocate() should protect here/ ======== Resume: for 1.: Beware if logging is configured to skip INFO messages. Of course, if context is stopped before request processing on it completes, some things are expected to fail. Tomcat waits here, the timeout is configurable. It is a tradeoff. An infinite wait is usually undesirable. See "unloadDelay" setting on Context. The default value is 2 seconds. http://tomcat.apache.org/tomcat-7.0-doc/config/context.html for 2. and 3.: These can be improved. for 4.: OK, nothing to do. -- You are receiving this mail because: You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org