This is an automated email from the ASF dual-hosted git repository. remm pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push: new 0c6c3d2 Track listeners added by the FrameworkListener to remove them later 0c6c3d2 is described below commit 0c6c3d2ebccb7400f904c5093450696b9e243746 Author: remm <r...@apache.org> AuthorDate: Mon Jun 3 18:02:54 2019 +0200 Track listeners added by the FrameworkListener to remove them later Avoid duplicate REMOVE_CHILD_EVENT notification, one for removeChild and a recursive one in child.destroy. --- java/org/apache/catalina/core/ContainerBase.java | 6 +++++- java/org/apache/catalina/core/FrameworkListener.java | 17 ++++++++++++++--- .../core/ThreadLocalLeakPreventionListener.java | 11 ----------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/java/org/apache/catalina/core/ContainerBase.java b/java/org/apache/catalina/core/ContainerBase.java index 8bbfaf8..ad99bf3 100644 --- a/java/org/apache/catalina/core/ContainerBase.java +++ b/java/org/apache/catalina/core/ContainerBase.java @@ -808,18 +808,22 @@ public abstract class ContainerBase extends LifecycleMBeanBase 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); } - fireContainerEvent(REMOVE_CHILD_EVENT, child); + if (!destroy) { + fireContainerEvent(REMOVE_CHILD_EVENT, child); + } synchronized(children) { if (children.get(child.getName()) == null) diff --git a/java/org/apache/catalina/core/FrameworkListener.java b/java/org/apache/catalina/core/FrameworkListener.java index 6e1944d..ba85ccb 100644 --- a/java/org/apache/catalina/core/FrameworkListener.java +++ b/java/org/apache/catalina/core/FrameworkListener.java @@ -17,6 +17,8 @@ package org.apache.catalina.core; +import java.util.concurrent.ConcurrentHashMap; + import org.apache.catalina.Container; import org.apache.catalina.ContainerEvent; import org.apache.catalina.ContainerListener; @@ -36,6 +38,9 @@ import org.apache.catalina.Service; */ public abstract class FrameworkListener implements LifecycleListener, ContainerListener { + protected final ConcurrentHashMap<Context, LifecycleListener> contextListeners = + new ConcurrentHashMap<>(); + /** * Create a lifecycle listener which will then be added to the specified context. * @param context the associated Context @@ -71,7 +76,6 @@ public abstract class FrameworkListener implements LifecycleListener, ContainerL registerListenersForEngine(engine); } } - } protected void registerListenersForEngine(Engine engine) { @@ -90,7 +94,9 @@ public abstract class FrameworkListener implements LifecycleListener, ContainerL } protected void registerContextListener(Context context) { - context.addLifecycleListener(createLifecycleListener(context)); + LifecycleListener listener = createLifecycleListener(context); + contextListeners.put(context, listener); + context.addLifecycleListener(listener); } protected void processContainerAddChild(Container child) { @@ -104,7 +110,12 @@ public abstract class FrameworkListener implements LifecycleListener, ContainerL } protected void processContainerRemoveChild(Container child) { - if (child instanceof Host || child instanceof Engine) { + if (child instanceof Context) { + LifecycleListener listener = contextListeners.remove(child); + if (listener != null) { + child.removeLifecycleListener(listener); + } + } else if (child instanceof Host || child instanceof Engine) { child.removeContainerListener(this); } } diff --git a/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java b/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java index eb33b18..58c4857 100644 --- a/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java +++ b/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java @@ -19,7 +19,6 @@ package org.apache.catalina.core; import java.util.concurrent.Executor; -import org.apache.catalina.Container; import org.apache.catalina.ContainerEvent; import org.apache.catalina.Context; import org.apache.catalina.Engine; @@ -107,16 +106,6 @@ public class ThreadLocalLeakPreventionListener extends FrameworkListener { } - @Override - protected void processContainerRemoveChild(Container child) { - if (child instanceof Context) { - Context context = (Context) child; - context.removeLifecycleListener(this); - } else { - super.processContainerRemoveChild(child); - } - } - /** * Updates each ThreadPoolExecutor with the current time, which is the time * when a context is being stopped. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org