From 7eec2000d72f8fa597398704121d0b73a84ca284 Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Thu, 25 Feb 2016 10:57:59 +0100 Subject: Fix possible race condition between Connection and Connectors The issue occurs with ProxiedConnection that started connecting but do not have an external reference anymore. As soon as the handlers of the ProxiedConnection are disconnected from the signals of the connection_ object, the remaining references to a shared ProxiedConnection vanish and the ProxiedConnection is deleted, while it still requires access to its members in ProxiedConnection::handleConnectFinished(). Test-Information: All tests pass on OS X 10.11.3. No TSAN reports on Debian 8 in a scenario with randomly connecting/disconnecting Client instances that use a HTTP proxy. Change-Id: I4d6d2c85013e066d9ed298aa9b913afc83949e35 diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp index 5510acb..2775c97 100644 --- a/Swiften/Network/Connector.cpp +++ b/Swiften/Network/Connector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -50,6 +50,10 @@ void Connector::start() { } void Connector::stop() { + if (currentConnection) { + currentConnection->onConnectFinished.disconnect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1)); + currentConnection->disconnect(); + } finish(boost::shared_ptr()); } diff --git a/Swiften/Network/ProxiedConnection.cpp b/Swiften/Network/ProxiedConnection.cpp index c44c1f5..69f719d 100644 --- a/Swiften/Network/ProxiedConnection.cpp +++ b/Swiften/Network/ProxiedConnection.cpp @@ -1,17 +1,15 @@ /* - * Copyright (c) 2012-2015 Isode Limited. + * Copyright (c) 2012-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ - #include -#include - #include #include +#include #include #include @@ -39,7 +37,7 @@ ProxiedConnection::~ProxiedConnection() { connection_->onDisconnected.disconnect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1)); } if (connected_) { - std::cerr << "Warning: Connection was still established." << std::endl; + SWIFT_LOG(warning) << "Connection was still established." << std::endl; } } @@ -65,8 +63,11 @@ void ProxiedConnection::listen() { } void ProxiedConnection::disconnect() { + cancelConnector(); connected_ = false; - connection_->disconnect(); + if (connection_) { + connection_->disconnect(); + } } void ProxiedConnection::handleDisconnected(const boost::optional& error) { -- cgit v0.10.2-6-g49f6