AMQ-6706 - Protecting preShutdownHooks with an AtomicBoolean

Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/2311749a
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/2311749a
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/2311749a

Branch: refs/heads/master
Commit: 2311749aa2629cf344fb5642910c3cc39f869b58
Parents: 3593afe
Author: Christopher L. Shannon (cshannon) <christopher.l.shan...@gmail.com>
Authored: Tue Jun 20 11:05:29 2017 -0400
Committer: Christopher L. Shannon (cshannon) <christopher.l.shan...@gmail.com>
Committed: Tue Jun 20 11:05:29 2017 -0400

----------------------------------------------------------------------
 .../apache/activemq/broker/BrokerService.java   | 21 +++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq/blob/2311749a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
----------------------------------------------------------------------
diff --git 
a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java 
b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
index 97fb814..c177b76 100644
--- 
a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
+++ 
b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
@@ -125,7 +125,6 @@ import org.apache.activemq.util.ServiceStopper;
 import org.apache.activemq.util.StoreUtil;
 import org.apache.activemq.util.ThreadPoolUtils;
 import org.apache.activemq.util.TimeUtils;
-import org.apache.activemq.util.URISupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
@@ -199,6 +198,7 @@ public class BrokerService implements Service {
     private final AtomicBoolean started = new AtomicBoolean(false);
     private final AtomicBoolean stopped = new AtomicBoolean(false);
     private final AtomicBoolean stopping = new AtomicBoolean(false);
+    private final AtomicBoolean preShutdownHooksInvoked = new 
AtomicBoolean(false);
     private BrokerPlugin[] plugins;
     private boolean keepDurableSubsActive = true;
     private boolean useVirtualTopics = true;
@@ -268,7 +268,7 @@ public class BrokerService implements Service {
     private boolean rollbackOnlyOnAsyncException = true;
 
     private int storeOpenWireVersion = OpenWireFormat.DEFAULT_STORE_VERSION;
-    private List<Runnable> preShutdownHooks = new CopyOnWriteArrayList<>();
+    private final List<Runnable> preShutdownHooks = new 
CopyOnWriteArrayList<>();
 
     static {
 
@@ -603,6 +603,7 @@ public class BrokerService implements Service {
 
         setStartException(null);
         stopping.set(false);
+        preShutdownHooksInvoked.set(false);
         startDate = new Date();
         MDC.put("activemq.broker", brokerName);
 
@@ -801,11 +802,17 @@ public class BrokerService implements Service {
     public void stop() throws Exception {
         final ServiceStopper stopper = new ServiceStopper();
 
-        for (Runnable hook : preShutdownHooks) {
-            try {
-                hook.run();
-            } catch (Throwable e) {
-                stopper.onException(hook, e);
+        //The preShutdownHooks need to run before stopping.compareAndSet()
+        //so there is a separate AtomicBoolean so the hooks only run once
+        //We want to make sure the hooks are run before stop is initialized
+        //including setting the stopping variable - See AMQ-6706
+        if (preShutdownHooksInvoked.compareAndSet(false, true)) {
+            for (Runnable hook : preShutdownHooks) {
+                try {
+                    hook.run();
+                } catch (Throwable e) {
+                    stopper.onException(hook, e);
+                }
             }
         }
 

Reply via email to