From 1e44e6b68bae11b25a9ce615e51236e089656e76 Mon Sep 17 00:00:00 2001 From: aljar Date: Wed, 19 Feb 2020 11:19:12 +0100 Subject: [PATCH] Fixed issue where the negotiate was overwritten by the handler and the connection was closed but still a timeout was triggered --- include/amqpcpp/connection.h | 11 ++++++++++- include/amqpcpp/connectionimpl.h | 13 ++++++++++++- include/amqpcpp/libev.h | 8 ++++---- include/amqpcpp/linux_tcp/tcpconnection.h | 15 +++++++++++++-- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/include/amqpcpp/connection.h b/include/amqpcpp/connection.h index ee4bb22..17cf635 100644 --- a/include/amqpcpp/connection.h +++ b/include/amqpcpp/connection.h @@ -197,13 +197,22 @@ public: } /** - * Is the connection ready to accept instructions / has passed the login handshake? + * Is the connection ready to accept instructions / has passed the login handshake and not closed? * @return bool */ bool ready() const { return _implementation.ready(); } + + /** + * Is (or was) the connection initialized + * @return bool + */ + bool initialized() const + { + return _implementation.initialized(); + } /** * Is the connection in a usable state, or is it already closed or diff --git a/include/amqpcpp/connectionimpl.h b/include/amqpcpp/connectionimpl.h index e9fa67d..6d9e32a 100644 --- a/include/amqpcpp/connectionimpl.h +++ b/include/amqpcpp/connectionimpl.h @@ -219,7 +219,7 @@ public: /** * Are we fully connected and ready for instructions? This is true after the initial - * protocol and login handshake were completed. + * protocol and login handshake were completed and the connection is not closed. * @return bool */ bool ready() const @@ -228,6 +228,17 @@ public: return _state == state_connected; } + /** + * Is (or was) the connection initialized + * @return bool + */ + bool initialized() const + { + // We are initalized if we have passed the initialized state. So we are in + // a connected, closing, or closed state. + return _state == state_connected || _state == state_closing || _state == state_closed; + } + /** * Are we closing down? * @return bool diff --git a/include/amqpcpp/libev.h b/include/amqpcpp/libev.h index 65508a2..110f251 100644 --- a/include/amqpcpp/libev.h +++ b/include/amqpcpp/libev.h @@ -234,7 +234,7 @@ private: // timer is no longer active, so the refcounter in the loop is restored ev_ref(_loop); - + // if the onNegotiate method was not yet called, and no heartbeat timeout was negotiated if (_timeout == 0) { @@ -243,10 +243,10 @@ private: // in either case we're no longer going to run further timers. _next = _expire = 0.0; - // if we have a valid connection, user-space must have overridden the onNegotiate + // if we have an initialized connection, user-space must have overridden the onNegotiate // method, so we keep using the connection - if (_connection->ready()) return; - + if (_connection->initialized()) return; + // this is a connection timeout, close the connection from our side too return (void)_connection->close(true); } diff --git a/include/amqpcpp/linux_tcp/tcpconnection.h b/include/amqpcpp/linux_tcp/tcpconnection.h index 5095be1..0e75314 100644 --- a/include/amqpcpp/linux_tcp/tcpconnection.h +++ b/include/amqpcpp/linux_tcp/tcpconnection.h @@ -57,7 +57,7 @@ private: * @friend */ friend TcpChannel; - + /** * Method that is called when the RabbitMQ server and your client application @@ -237,13 +237,24 @@ public: bool close(bool immediate = false); /** - * Is the connection connected, meaning: it has passed the login handshake? + * Is the connection connected, meaning: it has passed the login handshake + * and isn't closed yet? * @return bool */ bool ready() const { return _connection.ready(); } + + /** + * Is the connection initialized, meaning: it has passed the login handshake? + * It may be closing or closed + * @return bool + */ + bool initialized() const + { + return _connection.initialized(); + } /** * Is the connection in a usable state / not yet closed or being closed