Author: markt
Date: Wed Aug 29 13:06:30 2018
New Revision: 1839575

URL: http://svn.apache.org/viewvc?rev=1839575&view=rev
Log:
Ensure thread-local mapping data is always recycled

Modified:
    tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java

Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=1839575&r1=1839574&r2=1839575&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java Wed Aug 
29 13:06:30 2018
@@ -460,47 +460,52 @@ public class ApplicationContext implemen
         // Use the thread local mapping data
         MappingData mappingData = dd.mappingData;
 
-        // Map the URI
-        CharChunk uriCC = uriMB.getCharChunk();
         try {
-            uriCC.append(context.getPath(), 0, context.getPath().length());
-            /*
-             * Ignore any trailing path params (separated by ';') for mapping
-             * purposes
-             */
-            int semicolon = normalizedPath.indexOf(';');
-            if (pos >= 0 && semicolon > pos) {
-                semicolon = -1;
-            }
-            uriCC.append(normalizedPath, 0, semicolon > 0 ? semicolon : pos);
-            service.getMapper().map(context, uriMB, mappingData);
-            if (mappingData.wrapper == null) {
+            // Map the URI
+            CharChunk uriCC = uriMB.getCharChunk();
+            try {
+                uriCC.append(context.getPath(), 0, context.getPath().length());
+                /*
+                 * Ignore any trailing path params (separated by ';') for 
mapping
+                 * purposes
+                 */
+                int semicolon = normalizedPath.indexOf(';');
+                if (pos >= 0 && semicolon > pos) {
+                    semicolon = -1;
+                }
+                uriCC.append(normalizedPath, 0, semicolon > 0 ? semicolon : 
pos);
+                service.getMapper().map(context, uriMB, mappingData);
+                if (mappingData.wrapper == null) {
+                    return null;
+                }
+                /*
+                 * Append any trailing path params (separated by ';') that were
+                 * ignored for mapping purposes, so that they're reflected in 
the
+                 * RequestDispatcher's requestURI
+                 */
+                if (semicolon > 0) {
+                    uriCC.append(normalizedPath, semicolon, pos - semicolon);
+                }
+            } catch (Exception e) {
+                // Should never happen
+                log(sm.getString("applicationContext.mapping.error"), e);
                 return null;
             }
-            /*
-             * Append any trailing path params (separated by ';') that were
-             * ignored for mapping purposes, so that they're reflected in the
-             * RequestDispatcher's requestURI
-             */
-            if (semicolon > 0) {
-                uriCC.append(normalizedPath, semicolon, pos - semicolon);
-            }
-        } catch (Exception e) {
-            // Should never happen
-            log(sm.getString("applicationContext.mapping.error"), e);
-            return null;
-        }
 
-        Wrapper wrapper = mappingData.wrapper;
-        String wrapperPath = mappingData.wrapperPath.toString();
-        String pathInfo = mappingData.pathInfo.toString();
-        HttpServletMapping mapping = new 
ApplicationMapping(mappingData).getHttpServletMapping();
-
-        mappingData.recycle();
-
-        // Construct a RequestDispatcher to process this request
-        return new ApplicationDispatcher(wrapper, uri, wrapperPath, pathInfo,
-                queryString, mapping, null);
+            Wrapper wrapper = mappingData.wrapper;
+            String wrapperPath = mappingData.wrapperPath.toString();
+            String pathInfo = mappingData.pathInfo.toString();
+            HttpServletMapping mapping = new 
ApplicationMapping(mappingData).getHttpServletMapping();
+
+            // Construct a RequestDispatcher to process this request
+            return new ApplicationDispatcher(wrapper, uri, wrapperPath, 
pathInfo,
+                    queryString, mapping, null);
+        } finally {
+            // Recycle thread local data at the end of the request so 
references
+            // are not held to a completed request as there is potential for
+            // that to trigger a memory leak if a context is unloaded.
+            mappingData.recycle();
+        }
     }
 
 



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

Reply via email to