You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2019/06/03 16:03:06 UTC
[tomcat] branch master updated: Track listeners added by the
FrameworkListener to remove them later
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 <re...@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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org