|
32 | 32 | import java.net.SocketTimeoutException; |
33 | 33 | import java.util.*; |
34 | 34 | import java.util.concurrent.*; |
| 35 | +import java.util.concurrent.atomic.AtomicBoolean; |
35 | 36 |
|
36 | 37 | final class Copyright { |
37 | 38 | final static String COPYRIGHT="Copyright (c) 2007-2017 Pivotal Software, Inc."; |
@@ -63,6 +64,8 @@ public class AMQConnection extends ShutdownNotifierComponent implements Connecti |
63 | 64 |
|
64 | 65 | private final ErrorOnWriteListener errorOnWriteListener; |
65 | 66 |
|
| 67 | + private final AtomicBoolean finalShutdownStarted = new AtomicBoolean(false); |
| 68 | + |
66 | 69 | /** |
67 | 70 | * Retrieve a copy of the default table of client properties that |
68 | 71 | * will be sent to the server during connection startup. This |
@@ -700,14 +703,16 @@ private void handleFailure(Throwable ex) { |
700 | 703 |
|
701 | 704 | /** private API */ |
702 | 705 | public void doFinalShutdown() { |
703 | | - _frameHandler.close(); |
704 | | - _appContinuation.set(null); |
705 | | - notifyListeners(); |
706 | | - // assuming that shutdown listeners do not do anything |
707 | | - // asynchronously, e.g. start new threads, this effectively |
708 | | - // guarantees that we only begin recovery when all shutdown |
709 | | - // listeners have executed |
710 | | - notifyRecoveryCanBeginListeners(); |
| 706 | + if (finalShutdownStarted.compareAndSet(false, true)) { |
| 707 | + _frameHandler.close(); |
| 708 | + _appContinuation.set(null); |
| 709 | + notifyListeners(); |
| 710 | + // assuming that shutdown listeners do not do anything |
| 711 | + // asynchronously, e.g. start new threads, this effectively |
| 712 | + // guarantees that we only begin recovery when all shutdown |
| 713 | + // listeners have executed |
| 714 | + notifyRecoveryCanBeginListeners(); |
| 715 | + } |
711 | 716 | } |
712 | 717 |
|
713 | 718 | private void notifyRecoveryCanBeginListeners() { |
|
0 commit comments