From 640603172bde2cfbd3fc687fd7d2ba4e400e0849 Mon Sep 17 00:00:00 2001 From: markt Date: Thu, 4 Nov 2010 23:03:26 +0000 Subject: [PATCH] https://issues.apache.org/bugzilla/show_bug.cgi?id=50168 Add a DESTROYING state and associated events and use them to ensure Contexts are only destroyed once. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1031335 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/Lifecycle.java | 19 +++++++++++++------ java/org/apache/catalina/LifecycleState.java | 3 ++- .../apache/catalina/core/AprLifecycleListener.java | 2 +- java/org/apache/catalina/core/ContainerBase.java | 7 ++++++- java/org/apache/catalina/startup/ContextConfig.java | 2 +- java/org/apache/catalina/util/LifecycleBase.java | 7 +++++-- webapps/docs/changelog.xml | 7 +++++++ 7 files changed, 35 insertions(+), 12 deletions(-) diff --git a/java/org/apache/catalina/Lifecycle.java b/java/org/apache/catalina/Lifecycle.java index fe432e09b..5b540d30f 100644 --- a/java/org/apache/catalina/Lifecycle.java +++ b/java/org/apache/catalina/Lifecycle.java @@ -50,10 +50,11 @@ package org.apache.catalina; * | | | | | | * | | | |auto | | * | | | destroy() \|/ destroy() | | - * | | FAILED ---->------ DESTROYED ----<----------------- | - * | | ^ | - * | | destroy() | | - * | ------------------------------- | + * | | FAILED ---->------ DESTROYING ---<----------------- | + * | | ^ | | + * | | destroy() | |auto | + * | ----------------------------- \|/ | + * | DESTROYED | * | | * | stop() | * --->------------------------------>------------------------------ @@ -149,9 +150,15 @@ public interface Lifecycle { /** - * The LifecycleEvent type for the "component destroy" event. + * The LifecycleEvent type for the "component after destroy" event. */ - public static final String DESTROY_EVENT = "destroy"; + public static final String AFTER_DESTROY_EVENT = "after_destroy"; + + + /** + * The LifecycleEvent type for the "component before destroy" event. + */ + public static final String BEFORE_DESTROY_EVENT = "before_destroy"; /** diff --git a/java/org/apache/catalina/LifecycleState.java b/java/org/apache/catalina/LifecycleState.java index 5f2e3b7fd..3ddd48dec 100644 --- a/java/org/apache/catalina/LifecycleState.java +++ b/java/org/apache/catalina/LifecycleState.java @@ -31,7 +31,8 @@ public enum LifecycleState { STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT), STOPPING(false, Lifecycle.STOP_EVENT), STOPPED(false, Lifecycle.AFTER_STOP_EVENT), - DESTROYED(false, Lifecycle.DESTROY_EVENT), + DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT), + DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT), FAILED(false, null), MUST_STOP(true, null), MUST_DESTROY(true, null); diff --git a/java/org/apache/catalina/core/AprLifecycleListener.java b/java/org/apache/catalina/core/AprLifecycleListener.java index 5151ad3fc..401b41114 100644 --- a/java/org/apache/catalina/core/AprLifecycleListener.java +++ b/java/org/apache/catalina/core/AprLifecycleListener.java @@ -110,7 +110,7 @@ public class AprLifecycleListener } } } - } else if (Lifecycle.DESTROY_EVENT.equals(event.getType())) { + } else if (Lifecycle.AFTER_DESTROY_EVENT.equals(event.getType())) { synchronized (lock) { if (!aprAvailable) { return; diff --git a/java/org/apache/catalina/core/ContainerBase.java b/java/org/apache/catalina/core/ContainerBase.java index 04206b3e0..2b6c78bbb 100644 --- a/java/org/apache/catalina/core/ContainerBase.java +++ b/java/org/apache/catalina/core/ContainerBase.java @@ -959,7 +959,12 @@ public abstract class ContainerBase extends LifecycleMBeanBase // Set child's parent to null to prevent a loop child.setParent(null); try { - child.destroy(); + // 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(); + } } catch (LifecycleException e) { log.error("ContainerBase.removeChild: destroy: ", e); } diff --git a/java/org/apache/catalina/startup/ContextConfig.java b/java/org/apache/catalina/startup/ContextConfig.java index 32d375148..a8237eab6 100644 --- a/java/org/apache/catalina/startup/ContextConfig.java +++ b/java/org/apache/catalina/startup/ContextConfig.java @@ -332,7 +332,7 @@ public class ContextConfig configureStop(); } else if (event.getType().equals(Lifecycle.AFTER_INIT_EVENT)) { init(); - } else if (event.getType().equals(Lifecycle.DESTROY_EVENT)) { + } else if (event.getType().equals(Lifecycle.AFTER_DESTROY_EVENT)) { destroy(); } diff --git a/java/org/apache/catalina/util/LifecycleBase.java b/java/org/apache/catalina/util/LifecycleBase.java index b1850c63d..90502cf59 100644 --- a/java/org/apache/catalina/util/LifecycleBase.java +++ b/java/org/apache/catalina/util/LifecycleBase.java @@ -248,7 +248,8 @@ public abstract class LifecycleBase implements Lifecycle { @Override public synchronized final void destroy() throws LifecycleException { - if (LifecycleState.DESTROYED.equals(state)) { + if (LifecycleState.DESTROYING.equals(state) || + LifecycleState.DESTROYED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); @@ -265,9 +266,11 @@ public abstract class LifecycleBase implements Lifecycle { if (!state.equals(LifecycleState.STOPPED) && !state.equals(LifecycleState.FAILED) && !state.equals(LifecycleState.NEW)) { - invalidTransition(Lifecycle.DESTROY_EVENT); + invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT); } + setState(LifecycleState.DESTROYING); + destroyInternal(); setState(LifecycleState.DESTROYED); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index a64c7ed4d..29d52be79 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -80,6 +80,13 @@ resource. The default value is true, which will return the same instance of the resource in every JNDI lookup. (markt) + + 50168: Separate the Lifecycle.DESTROY_EVENT into + Lifecycle.BEFORE_DESTROY_EVENT and + Lifecycle.AFTER_DESTROY_EVENT. Use the additional state to + ensure that Context objects are only destroyed once. + (markt) + Improve debug logging for MapperListener registration. (markt) -- 2.11.0