[jboss-cvs] JBossAS SVN: r57337 - in branches/JBoss_4_0_2_CP: cluster/src/main/org/jboss/ha/framework/server system/src/main/org/jboss/deployment/scanner

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sun Oct 1 20:25:36 EDT 2006


Author: ryan.campbell at jboss.com
Date: 2006-10-01 20:25:35 -0400 (Sun, 01 Oct 2006)
New Revision: 57337

Modified:
   branches/JBoss_4_0_2_CP/cluster/src/main/org/jboss/ha/framework/server/FarmMemberService.java
   branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/AbstractDeploymentScanner.java
   branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/DeploymentScanner.java
Log:
ASPATCH-41: JBAS-3049: Deadlock in ScannerThread

Modified: branches/JBoss_4_0_2_CP/cluster/src/main/org/jboss/ha/framework/server/FarmMemberService.java
===================================================================
--- branches/JBoss_4_0_2_CP/cluster/src/main/org/jboss/ha/framework/server/FarmMemberService.java	2006-10-02 00:00:08 UTC (rev 57336)
+++ branches/JBoss_4_0_2_CP/cluster/src/main/org/jboss/ha/framework/server/FarmMemberService.java	2006-10-02 00:25:35 UTC (rev 57337)
@@ -157,7 +157,7 @@
       scannerThread.doScan();
 
       // enable scanner thread if we are enabled
-      scannerThread.setEnabled(scanEnabled.get());
+      scannerThread.setEnabled(isScanEnabled());
    }
    
 

Modified: branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/AbstractDeploymentScanner.java
===================================================================
--- branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/AbstractDeploymentScanner.java	2006-10-02 00:00:08 UTC (rev 57336)
+++ branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/AbstractDeploymentScanner.java	2006-10-02 00:25:35 UTC (rev 57337)
@@ -1,12 +1,24 @@
-/***************************************
- *                                     *
- *  JBoss: The OpenSource J2EE WebOS   *
- *                                     *
- *  Distributable under LGPL license.  *
- *  See terms of license at gnu.org.   *
- *                                     *
- ***************************************/
-
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
 package org.jboss.deployment.scanner;
 
 import javax.management.ObjectName;
@@ -14,14 +26,14 @@
 import org.jboss.deployment.Deployer;
 import org.jboss.deployment.MainDeployerMBean;
 import org.jboss.logging.Logger;
+import org.jboss.mx.util.MBeanProxyExt;
+import org.jboss.mx.util.MBeanProxyInstance;
 import org.jboss.system.MissingAttributeException;
 import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.util.MuBoolean;
-import org.jboss.util.MuLong;
 import org.jboss.util.NullArgumentException;
-import org.jboss.mx.util.MBeanProxyExt;
-import org.jboss.mx.util.MBeanProxyInstance;
 
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
+
 /**
  * An abstract support class for implementing a deployment scanner.
  *
@@ -34,16 +46,18 @@
  * @author  <a href="mailto:jason at planet57.com">Jason Dillon</a>
  * @author Scott.Stark at jboss.org
  */
-public abstract class AbstractDeploymentScanner
-   extends ServiceMBeanSupport
+public abstract class AbstractDeploymentScanner extends ServiceMBeanSupport
    implements DeploymentScanner, DeploymentScannerMBean
 {
    /** The scan period in milliseconds */
-   protected MuLong scanPeriod = new MuLong(5000);
+   protected long scanPeriod = 5000;
 
    /** True if period based scanning is enabled. */
-   protected MuBoolean scanEnabled = new MuBoolean(true);
+   protected boolean scanEnabled = true;
 
+   /** The stop timeout */
+   protected long stopTimeOut = 60000;
+   
    /** A proxy to the deployer we are using. */
    protected Deployer deployer;
 
@@ -82,24 +96,34 @@
       if (period < 0)
          throw new IllegalArgumentException("ScanPeriod must be >= 0; have: " + period);
 
-      this.scanPeriod.set(period);
+      this.scanPeriod = period;
    }
 
    public long getScanPeriod()
    {
-      return scanPeriod.longValue();
+      return scanPeriod;
    }
 
    public void setScanEnabled(final boolean flag)
    {
-      this.scanEnabled.set(flag);
+      this.scanEnabled = flag;
    }
 
    public boolean isScanEnabled()
    {
-      return scanEnabled.get();
+      return scanEnabled;
    }
 
+   public long getStopTimeOut()
+   {
+      return stopTimeOut;
+   }
+
+   public void setStopTimeOut(long stopTimeOut)
+   {
+      this.stopTimeOut = stopTimeOut;
+   }
+
    /** This is here to work around a bug in the IBM vm that causes an
     * AbstractMethodError to be thrown when the ScannerThread calls scan.
     * @throws Exception
@@ -119,84 +143,119 @@
       extends Thread
    {
       /** We get our own logger. */
-      protected Logger log = Logger.getLogger(ScannerThread.class);
+      protected Logger scannerLog = Logger.getLogger(ScannerThread.class);
 
       /** True if the scan loop should run. */
-      protected boolean enabled;
+      protected SynchronizedBoolean enabled = new SynchronizedBoolean(false);
 
       /** True if we are shutting down. */
-      protected boolean shuttingDown;
+      protected SynchronizedBoolean shuttingDown = new SynchronizedBoolean(false);
 
       /** Lock/notify object. */
       protected Object lock = new Object();
 
+      /** Active synchronization. */
+      protected SynchronizedBoolean active = new SynchronizedBoolean(false);
+
       public ScannerThread(boolean enabled)
       {
          super("ScannerThread");
 
-         this.enabled = enabled;
+         this.enabled.set(enabled);
       }
 
       public void setEnabled(boolean enabled)
       {
-         this.enabled = enabled;
+         this.enabled.set(enabled);
 
          synchronized (lock)
          {
             lock.notifyAll();
          }
-
-         if (log.isDebugEnabled())
-         {
-            log.debug("Notified that enabled: " + enabled);
-         }
+         
+         scannerLog.debug("Notified that enabled: " + enabled);
       }
 
       public void shutdown()
       {
-         enabled = false;
-         shuttingDown = true;
+         enabled.set(false);
+         shuttingDown.set(true);
 
          synchronized (lock)
          {
             lock.notifyAll();
          }
 
-         if (log.isDebugEnabled())
-         {
-            log.debug("Notified to shutdown");
-         }
+         scannerLog.debug("Notified to shutdown");
 
          // jason: shall we also interrupt this thread?
       }
     
       public void run()
       {
-         log.debug("Running");
+         scannerLog.debug("Running");
 
-         while (!shuttingDown)
+         active.set(true);
+         try
          {
-
-            // If we are not enabled, then wait
-            if (!enabled)
+            while (shuttingDown.get() == false)
             {
-               try
+               // If we are not enabled, then wait
+               if (enabled.get() == false)
                {
-                  log.debug("Disabled, waiting for notification");
-                  synchronized (lock)
+                  synchronized (active)
                   {
-                     lock.wait();
+                     active.set(false);
+                     active.notifyAll();
                   }
+                  try
+                  {
+                     scannerLog.debug("Disabled, waiting for notification");
+                     synchronized (lock)
+                     {
+                        lock.wait();
+                     }
+                  }
+                  catch (InterruptedException ignore)
+                  {
+                  }
+                  active.set(true);
                }
-               catch (InterruptedException ignore) {}
+
+               loop();
             }
+         }
+         finally
+         {
+            synchronized (active)
+            {
+               active.set(false);
+               active.notifyAll();
+            }
+         }
+         
+         scannerLog.debug("Shutdown");
+      }
 
-            loop();
+      protected void waitForInactive()
+      {
+         boolean interrupted = false;
+         synchronized (active)
+         {
+            try
+            {
+               if (active.get())
+                  active.wait(stopTimeOut);
+            }
+            catch (InterruptedException ignored)
+            {
+               interrupted = true;
+            }
          }
-
-         log.debug("Shutdown");
+         if (interrupted)
+            Thread.currentThread().interrupt();
       }
-
+      
       public void doScan()
       {
          // Scan for new/removed/changed/whatever
@@ -204,21 +263,21 @@
             scan();
          }
          catch (Exception e) {
-            log.error("Scanning failed; continuing", e);
+            scannerLog.error("Scanning failed; continuing", e);
          }
       }
       
       protected void loop()
       {
-         while (enabled)
+         while (enabled.get() && shuttingDown.get() == false)
          {
             doScan();
 
             // Sleep for scan period
             try
             {
-               log.trace("Sleeping...");
-               Thread.sleep(scanPeriod.longValue());
+               scannerLog.trace("Sleeping...");
+               Thread.sleep(scanPeriod);
             }
             catch (InterruptedException ignore) {}
          }
@@ -251,11 +310,11 @@
       final ScannerThread _scannerThread = scannerThread;
       shutdownHook = new Thread("DeploymentScanner Shutdown Hook")
          {
-            ScannerThread scannerThread = _scannerThread;
+            ScannerThread thread = _scannerThread;
             
             public void run()
             {
-               scannerThread.shutdown();
+               thread.shutdown();
             }
          };
       
@@ -277,7 +336,7 @@
          scannerThread.doScan();
 
          // enable scanner thread if we are enabled
-         scannerThread.setEnabled(scanEnabled.get());
+         scannerThread.setEnabled(scanEnabled);
       }
    }
    
@@ -285,7 +344,10 @@
    {
       // disable scanner thread
       if( scannerThread != null )
+      {
          scannerThread.setEnabled(false);
+         scannerThread.waitForInactive();
+      }
    }
 
    protected void destroyService() throws Exception 

Modified: branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/DeploymentScanner.java
===================================================================
--- branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/DeploymentScanner.java	2006-10-02 00:00:08 UTC (rev 57336)
+++ branches/JBoss_4_0_2_CP/system/src/main/org/jboss/deployment/scanner/DeploymentScanner.java	2006-10-02 00:25:35 UTC (rev 57337)
@@ -1,12 +1,24 @@
-/***************************************
- *                                     *
- *  JBoss: The OpenSource J2EE WebOS   *
- *                                     *
- *  Distributable under LGPL license.  *
- *  See terms of license at gnu.org.   *
- *                                     *
- ***************************************/
-
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
 package org.jboss.deployment.scanner;
 
 import javax.management.ObjectName;
@@ -84,8 +96,26 @@
     * @jmx:managed-attribute
     */
    boolean isScanEnabled();
+   
+   /**
+    * How long to wait in stop for the background thread to stop
+    * 
+    * @return the time in milliseconds.
+    *
+    * @jmx:managed-attribute
+    */
+   long getStopTimeOut();
 
    /**
+    * How long to wait in stop for the background thread to stop
+    * 
+    * @param stopTimeOut the time in milliseconds.
+    *
+    * @jmx:managed-attribute
+    */
+   void setStopTimeOut(long stopTimeOut);
+
+   /**
     * Scan for deployment changes.
     *
     * @throws IllegalStateException    Not initialized.




More information about the jboss-cvs-commits mailing list