You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2011/11/29 20:48:05 UTC

svn commit: r1208046 - in /tomcat/trunk/java/org/apache/catalina/core: ContainerBase.java StandardContext.java

Author: markt
Date: Tue Nov 29 19:48:04 2011
New Revision: 1208046

URL: http://svn.apache.org/viewvc?rev=1208046&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=52259
Regression caused by bug 46264. Prevent deadlock if no Realm is
configured.

Modified:
    tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java
    tomcat/trunk/java/org/apache/catalina/core/StandardContext.java

Modified: tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java?rev=1208046&r1=1208045&r2=1208046&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/ContainerBase.java Tue Nov 29 19:48:04 2011
@@ -33,6 +33,9 @@ import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import javax.management.ObjectName;
 import javax.naming.directory.DirContext;
@@ -234,10 +237,15 @@ public abstract class ContainerBase exte
     /**
      * The Realm with which this Container is associated.
      */
-    protected Realm realm = null;
+    private volatile Realm realm = null;
 
 
     /**
+     * Lock used to control access to the Realm.
+     */
+    private ReadWriteLock realmLock = new ReentrantReadWriteLock();
+
+    /**
      * The resources DirContext object with which this Container is associated.
      */
     protected DirContext resources = null;
@@ -695,11 +703,17 @@ public abstract class ContainerBase exte
     @Override
     public Realm getRealm() {
 
-        if (realm != null)
-            return (realm);
-        if (parent != null)
-            return (parent.getRealm());
-        return (null);
+        Lock l = realmLock.readLock();
+        try {
+            l.lock();
+            if (realm != null)
+                return (realm);
+            if (parent != null)
+                return (parent.getRealm());
+            return (null);
+        } finally {
+            l.unlock();
+        }
 
     }
 
@@ -710,38 +724,46 @@ public abstract class ContainerBase exte
      * @param realm The newly associated Realm
      */
     @Override
-    public synchronized void setRealm(Realm realm) {
+    public void setRealm(Realm realm) {
 
-        // Change components if necessary
-        Realm oldRealm = this.realm;
-        if (oldRealm == realm)
-            return;
-        this.realm = realm;
+        Lock l = realmLock.writeLock();
 
-        // Stop the old component if necessary
-        if (getState().isAvailable() && (oldRealm != null) &&
-            (oldRealm instanceof Lifecycle)) {
-            try {
-                ((Lifecycle) oldRealm).stop();
-            } catch (LifecycleException e) {
-                log.error("ContainerBase.setRealm: stop: ", e);
+        try {
+            l.lock();
+
+            // Change components if necessary
+            Realm oldRealm = realm;
+            if (oldRealm == realm)
+                return;
+            this.realm = realm;
+
+            // Stop the old component if necessary
+            if (getState().isAvailable() && (oldRealm != null) &&
+                (oldRealm instanceof Lifecycle)) {
+                try {
+                    ((Lifecycle) oldRealm).stop();
+                } catch (LifecycleException e) {
+                    log.error("ContainerBase.setRealm: stop: ", e);
+                }
             }
-        }
 
-        // Start the new component if necessary
-        if (realm != null)
-            realm.setContainer(this);
-        if (getState().isAvailable() && (realm != null) &&
-            (realm instanceof Lifecycle)) {
-            try {
-                ((Lifecycle) realm).start();
-            } catch (LifecycleException e) {
-                log.error("ContainerBase.setRealm: start: ", e);
+            // Start the new component if necessary
+            if (realm != null)
+                realm.setContainer(this);
+            if (getState().isAvailable() && (realm != null) &&
+                (realm instanceof Lifecycle)) {
+                try {
+                    ((Lifecycle) realm).start();
+                } catch (LifecycleException e) {
+                    log.error("ContainerBase.setRealm: start: ", e);
+                }
             }
-        }
 
-        // Report this property change to interested listeners
-        support.firePropertyChange("realm", oldRealm, this.realm);
+            // Report this property change to interested listeners
+            support.firePropertyChange("realm", oldRealm, this.realm);
+        } finally {
+            l.unlock();
+        }
 
     }
 
@@ -1060,6 +1082,7 @@ public abstract class ContainerBase exte
             ((Lifecycle) manager).start();
         if ((cluster != null) && (cluster instanceof Lifecycle))
             ((Lifecycle) cluster).start();
+        Realm realm = getRealm();
         if ((realm != null) && (realm instanceof Lifecycle))
             ((Lifecycle) realm).start();
         if ((resources != null) && (resources instanceof Lifecycle))
@@ -1146,6 +1169,7 @@ public abstract class ContainerBase exte
         if ((resources != null) && (resources instanceof Lifecycle)) {
             ((Lifecycle) resources).stop();
         }
+        Realm realm = getRealm();
         if ((realm != null) && (realm instanceof Lifecycle)) {
             ((Lifecycle) realm).stop();
         }
@@ -1297,6 +1321,7 @@ public abstract class ContainerBase exte
                 log.warn(sm.getString("containerBase.backgroundProcess.manager", manager), e);
             }
         }
+        Realm realm = getRealm();
         if (realm != null) {
             try {
                 realm.backgroundProcess();

Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1208046&r1=1208045&r2=1208046&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Tue Nov 29 19:48:04 2011
@@ -82,6 +82,7 @@ import org.apache.catalina.LifecycleStat
 import org.apache.catalina.Loader;
 import org.apache.catalina.Manager;
 import org.apache.catalina.Pipeline;
+import org.apache.catalina.Realm;
 import org.apache.catalina.Valve;
 import org.apache.catalina.Wrapper;
 import org.apache.catalina.deploy.ApplicationParameter;
@@ -5032,6 +5033,7 @@ public class StandardContext extends Con
 
                 if ((cluster != null) && (cluster instanceof Lifecycle))
                     ((Lifecycle) cluster).start();
+                Realm realm = getRealm();
                 if ((realm != null) && (realm instanceof Lifecycle))
                     ((Lifecycle) realm).start();
                 if ((resources != null) && (resources instanceof Lifecycle))
@@ -5378,6 +5380,7 @@ public class StandardContext extends Con
             // Stop resources
             resourcesStop();
 
+            Realm realm = getRealm();
             if ((realm != null) && (realm instanceof Lifecycle)) {
                 ((Lifecycle) realm).stop();
             }
@@ -5442,6 +5445,7 @@ public class StandardContext extends Con
         if ((manager != null) && (manager instanceof Lifecycle)) {
             ((Lifecycle) manager).destroy();
         }
+        Realm realm = getRealm();
         if ((realm != null) && (realm instanceof Lifecycle)) {
             ((Lifecycle) realm).destroy();
         }



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