This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/11.0.x by this push:
     new 4e4565e7c4 Fix container cleanup edge cases
4e4565e7c4 is described below

commit 4e4565e7c496791832f07d1652a6aaf4fc2ed3ab
Author: remm <[email protected]>
AuthorDate: Thu May 21 10:56:42 2026 +0200

    Fix container cleanup edge cases
    
    The remove event should be sent if the child container is actually
    removed, not based on some other factor.
    The framework listener should self clean a bit more when removing a
    container. Normally the children would be removed first, but doing this
    does not hurt.
---
 java/org/apache/catalina/core/ContainerBase.java     | 13 ++++++-------
 java/org/apache/catalina/core/FrameworkListener.java |  4 ++++
 webapps/docs/changelog.xml                           |  3 +++
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/java/org/apache/catalina/core/ContainerBase.java 
b/java/org/apache/catalina/core/ContainerBase.java
index 70b8e9ec95..47c2290418 100644
--- a/java/org/apache/catalina/core/ContainerBase.java
+++ b/java/org/apache/catalina/core/ContainerBase.java
@@ -646,30 +646,29 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
             log.error(sm.getString("containerBase.child.stop"), e);
         }
 
-        boolean destroy = false;
         try {
             // child.destroy() may have already been called which would have
             // triggered this call. If that is the case, no need to destroy the
             // child again.
             if (!LifecycleState.DESTROYING.equals(child.getState())) {
                 child.destroy();
-                destroy = true;
             }
         } catch (LifecycleException e) {
             log.error(sm.getString("containerBase.child.destroy"), e);
         }
 
-        if (!destroy) {
-            fireContainerEvent(REMOVE_CHILD_EVENT, child);
-        }
-
+        boolean removed = false;
         childrenLock.writeLock().lock();
         try {
-            children.remove(child.getName());
+            removed = children.remove(child.getName()) != null;
         } finally {
             childrenLock.writeLock().unlock();
         }
 
+        if (removed) {
+            fireContainerEvent(REMOVE_CHILD_EVENT, child);
+        }
+
     }
 
 
diff --git a/java/org/apache/catalina/core/FrameworkListener.java 
b/java/org/apache/catalina/core/FrameworkListener.java
index b3850ef9bf..c8b8c95cf3 100644
--- a/java/org/apache/catalina/core/FrameworkListener.java
+++ b/java/org/apache/catalina/core/FrameworkListener.java
@@ -153,6 +153,10 @@ public abstract class FrameworkListener implements 
LifecycleListener, ContainerL
             }
         } else if (child instanceof Host || child instanceof Engine) {
             child.removeContainerListener(this);
+            Container[] children = child.findChildren();
+            for (Container current : children) {
+                processContainerRemoveChild(current);
+            }
         }
     }
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 406791beb9..a6bb184bd4 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -149,6 +149,9 @@
         similar to what is done for servlets, as required by the servlet
         specification. (remm)
       </fix>
+      <fix>
+        Fix container event cleanups in some edge cases. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to