fixed bug when connection goes out of scope

This commit is contained in:
Aljar Meesters 2016-03-04 17:34:28 +01:00
parent a5e86d4b95
commit 70a7565c4e
2 changed files with 17 additions and 27 deletions

View File

@ -34,9 +34,11 @@ private:
/** /**
* The state of the TCP connection - this state objecs changes based on * The state of the TCP connection - this state objecs changes based on
* the state of the connection (resolving, connected or closed) * the state of the connection (resolving, connected or closed)
* @var TcpState * a shared pointer is used because we use a forward declaration, which isn't
* allowed in a unique pointer
* @var std::shared_ptr<TcpState>
*/ */
TcpState *_state = nullptr; std::shared_ptr<TcpState> _state;
/** /**
* The underlying AMQP connection * The underlying AMQP connection
@ -113,7 +115,7 @@ public:
/** /**
* Destructor * Destructor
*/ */
virtual ~TcpConnection(); virtual ~TcpConnection() = default;
/** /**
* Process the TCP connection * Process the TCP connection

View File

@ -27,15 +27,6 @@ TcpConnection::TcpConnection(TcpHandler *handler, const Address &address) :
_state(new TcpResolver(this, address.hostname(), address.port(), handler)), _state(new TcpResolver(this, address.hostname(), address.port(), handler)),
_connection(this, address.login(), address.vhost()) {} _connection(this, address.login(), address.vhost()) {}
/**
* Destructor
*/
TcpConnection::~TcpConnection()
{
// remove the state object
delete _state;
}
/** /**
* Process the TCP connection * Process the TCP connection
* This method should be called when the filedescriptor that is registered * This method should be called when the filedescriptor that is registered
@ -59,13 +50,10 @@ void TcpConnection::process(int fd, int flags)
// skip if the same state is continued to be used, or when the process() // skip if the same state is continued to be used, or when the process()
// method returns nullptr (which only happens when the object is destructed, // method returns nullptr (which only happens when the object is destructed,
// and "this" is no longer valid) // and "this" is no longer valid)
if (!result || result == _state) return; if (!result || result == _state.get()) return;
// remove old state
delete _state;
// replace it with the new implementation // replace it with the new implementation
_state = result; _state.reset(result);
} }
/** /**
@ -88,7 +76,7 @@ uint16_t TcpConnection::onNegotiate(Connection *connection, uint16_t interval)
*/ */
void TcpConnection::onData(Connection *connection, const char *buffer, size_t size) void TcpConnection::onData(Connection *connection, const char *buffer, size_t size)
{ {
// send the data over the connecction // send the data over the connection
_state->send(buffer, size); _state->send(buffer, size);
} }
@ -109,11 +97,11 @@ void TcpConnection::onHeartbeat(Connection *connection)
*/ */
void TcpConnection::onError(Connection *connection, const char *message) void TcpConnection::onError(Connection *connection, const char *message)
{ {
// current object is going to be removed, wrap it in a unique pointer to enforce that // current object is going to be removed, but we have to keep it for a while
std::unique_ptr<TcpState> ptr(_state); auto ptr = std::move(_state);
// object is now in a closed state // object is now in a closed state
_state = new TcpClosed(_state); _state.reset(new TcpClosed(ptr.get()));
// tell the implementation to report the error // tell the implementation to report the error
ptr->reportError(message); ptr->reportError(message);
@ -135,13 +123,13 @@ void TcpConnection::onConnected(Connection *connection)
*/ */
void TcpConnection::onClosed(Connection *connection) void TcpConnection::onClosed(Connection *connection)
{ {
// current object is going to be removed, wrap it in a unique pointer to enforce that // current object is going to be removed, but we have to keep it for a while
std::unique_ptr<TcpState> ptr(_state); auto ptr = std::move(_state);
// object is now in a closed state // object is now in a closed state
_state = new TcpClosed(_state); _state.reset(new TcpClosed(ptr.get()));
// tell the implementation to report the error // tell the implementation to report that connection is closed now
ptr->reportClosed(); ptr->reportClosed();
} }