@@ -103,6 +103,9 @@ public class AMQConnection extends ShutdownNotifierComponent implements Connecti
103103 */
104104 public BlockingCell <Object > _appContinuation = new BlockingCell <Object >();
105105
106+ /** Flag indicating whether the client received Connection.Close message from the broker */
107+ public boolean _brokerInitiatedShutdown = false ;
108+
106109 /**
107110 * Protected API - respond, in the driver thread, to a ShutdownSignal.
108111 * @param channelNumber the number of the channel to disconnect
@@ -191,6 +194,7 @@ public AMQConnection(ConnectionParameters params,
191194 _missedHeartbeats = 0 ;
192195 _heartbeat = 0 ;
193196 _exceptionHandler = exceptionHandler ;
197+ _brokerInitiatedShutdown = false ;
194198
195199 new MainLoop (); // start the main loop going
196200
@@ -457,26 +461,15 @@ public MainLoop() {
457461 }
458462 }
459463 } catch (EOFException ex ) {
460- if (isOpen ()) {
461- System .err .println ("AMQConnection.mainLoop: connection close" );
462- shutdown (ex , false , ex );
463- }
464+ if (!_brokerInitiatedShutdown )
465+ shutdown (ex , false , ex , true );
464466 } catch (Throwable ex ) {
465467 _exceptionHandler .handleUnexpectedConnectionDriverException (AMQConnection .this ,
466468 ex );
467- if (isOpen ()) {
468- shutdown (ex , false , ex );
469- }
469+ shutdown (ex , false , ex , true );
470470 } finally {
471471 // Finally, shut down our underlying data connection.
472472 _frameHandler .close ();
473-
474- // Set shutdown exception for any outstanding rpc,
475- // so that it does not wait infinitely for Connection.CloseOk.
476- // This can only happen when the broker closed the socket
477- // unexpectedly.
478- _channel0 .notifyOutstandingRpc (_shutdownCause );
479-
480473 _appContinuation .set (null );
481474 notifyListeners ();
482475 }
@@ -562,18 +555,22 @@ public boolean processControlCommand(Command c)
562555 }
563556
564557 public void handleConnectionClose (Command closeCommand ) {
565- shutdown (closeCommand , false , null );
558+ ShutdownSignalException sse = shutdown (closeCommand , false , null , false );
566559 try {
567560 _channel0 .quiescingTransmit (new AMQImpl .Connection .CloseOk ());
568561 } catch (IOException ioe ) {
569562 Utility .emptyStatement ();
570563 }
571- _heartbeat = 0 ; // Do not try to send heartbeats after CloseOk
572- new SocketCloseWait ();
564+ _heartbeat = 0 ; // Do not try to send heartbeats after CloseOk
565+ _brokerInitiatedShutdown = true ;
566+ new SocketCloseWait (sse );
573567 }
574568
575569 private class SocketCloseWait extends Thread {
576- public SocketCloseWait () {
570+ private ShutdownSignalException cause ;
571+
572+ public SocketCloseWait (ShutdownSignalException sse ) {
573+ cause = sse ;
577574 start ();
578575 }
579576
@@ -586,6 +583,7 @@ public SocketCloseWait() {
586583 _frameHandler .close ();
587584 } finally {
588585 _running = false ;
586+ _channel0 .notifyOutstandingRpc (cause );
589587 }
590588 }
591589 }
@@ -594,27 +592,26 @@ public SocketCloseWait() {
594592 * Protected API - causes all attached channels to terminate with
595593 * a ShutdownSignal built from the argument, and stops this
596594 * connection from accepting further work from the application.
595+ *
596+ * @return a shutdown signal built using the given arguments
597597 */
598- public void shutdown (Object reason ,
598+ public ShutdownSignalException shutdown (Object reason ,
599599 boolean initiatedByApplication ,
600- Throwable cause )
600+ Throwable cause ,
601+ boolean notifyRpc )
601602 {
602- try {
603- synchronized (this ) {
603+ ShutdownSignalException sse = new ShutdownSignalException (true ,initiatedByApplication ,
604+ reason , this );
605+ sse .initCause (cause );
606+ synchronized (this ) {
607+ if (initiatedByApplication )
604608 ensureIsOpen (); // invariant: we should never be shut down more than once per instance
605- ShutdownSignalException sse = new ShutdownSignalException (true ,
606- initiatedByApplication ,
607- reason , this );
608- sse .initCause (cause );
609+ if (isOpen ())
609610 _shutdownCause = sse ;
610- }
611-
612- _channel0 .processShutdownSignal (_shutdownCause );
613- } catch (AlreadyClosedException ace ) {
614- if (initiatedByApplication )
615- throw ace ;
616611 }
617- _channelManager .handleSignal (_shutdownCause );
612+ _channel0 .processShutdownSignal (sse , !initiatedByApplication , notifyRpc );
613+ _channelManager .handleSignal (sse );
614+ return sse ;
618615 }
619616
620617 public void close ()
@@ -690,7 +687,7 @@ public void close(int closeCode,
690687 try {
691688 AMQImpl .Connection .Close reason =
692689 new AMQImpl .Connection .Close (closeCode , closeMessage , 0 , 0 );
693- shutdown (reason , initiatedByApplication , cause );
690+ shutdown (reason , initiatedByApplication , cause , true );
694691 AMQChannel .SimpleBlockingRpcContinuation k =
695692 new AMQChannel .SimpleBlockingRpcContinuation ();
696693 _channel0 .quiescingRpc (reason , k );
0 commit comments