Skip to content

Commit

Permalink
Explicitly disconnect from remaining resources in destructors
Browse files Browse the repository at this point in the history
Explicitly disconnect from remaining resources in the
ChainedConnected and ClientSessionStanzaChannel destructors, so
the event loop will not call the signal handler methods on a
freed object.

Test-Information:

Repeating the test case of creating a Swift::Client instance,
connecting it and then deleting it after a random time below one
second.

On Mac OS X 10.9.5 running this test case causes two ASAN
heap-use-after-free errors and with this patch the errors are
gone.

Change-Id: I3e48150c3633f4076ca9172aad9e85ba389df950
  • Loading branch information
tfar committed Jul 21, 2015
1 parent 02ecf91 commit 6ca201d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
15 changes: 13 additions & 2 deletions Swiften/Client/ClientSessionStanzaChannel.cpp
@@ -1,16 +1,27 @@
/*
* Copyright (c) 2010 Isode Limited.
* Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/

#include <Swiften/Client/ClientSessionStanzaChannel.h>

#include <boost/bind.hpp>
#include <iostream>

#include <boost/bind.hpp>

namespace Swift {

ClientSessionStanzaChannel::~ClientSessionStanzaChannel() {
if (session) {
session->onFinished.disconnect(boost::bind(&ClientSessionStanzaChannel::handleSessionFinished, this, _1));
session->onStanzaReceived.disconnect(boost::bind(&ClientSessionStanzaChannel::handleStanza, this, _1));
session->onStanzaAcked.disconnect(boost::bind(&ClientSessionStanzaChannel::handleStanzaAcked, this, _1));
session->onInitialized.disconnect(boost::bind(&ClientSessionStanzaChannel::handleSessionInitialized, this));
session.reset();
}
}

void ClientSessionStanzaChannel::setSession(boost::shared_ptr<ClientSession> session) {
assert(!this->session);
this->session = session;
Expand Down
4 changes: 3 additions & 1 deletion Swiften/Client/ClientSessionStanzaChannel.h
Expand Up @@ -12,8 +12,8 @@
#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Client/ClientSession.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/IQ.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/Presence.h>

namespace Swift {
Expand All @@ -22,6 +22,8 @@ namespace Swift {
*/
class SWIFTEN_API ClientSessionStanzaChannel : public StanzaChannel {
public:
virtual ~ClientSessionStanzaChannel();

void setSession(boost::shared_ptr<ClientSession> session);

void sendIQ(boost::shared_ptr<IQ> iq);
Expand Down
15 changes: 12 additions & 3 deletions Swiften/Network/ChainedConnector.cpp
@@ -1,18 +1,19 @@
/*
* Copyright (c) 2011 Isode Limited.
* Copyright (c) 2011-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/

#include <Swiften/Network/ChainedConnector.h>

#include <boost/bind.hpp>
#include <typeinfo>

#include <boost/bind.hpp>

#include <Swiften/Base/Log.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Network/Connector.h>
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/Connector.h>

using namespace Swift;

Expand All @@ -32,6 +33,14 @@ ChainedConnector::ChainedConnector(
timeoutMilliseconds(0) {
}

ChainedConnector::~ChainedConnector() {
if (currentConnector) {
currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1, _2));
currentConnector->stop();
currentConnector.reset();
}
}

void ChainedConnector::setTimeoutMilliseconds(int milliseconds) {
timeoutMilliseconds = milliseconds;
}
Expand Down
10 changes: 6 additions & 4 deletions Swiften/Network/ChainedConnector.h
@@ -1,20 +1,21 @@
/*
* Copyright (c) 2011 Isode Limited.
* Copyright (c) 2011-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/

#pragma once

#include <deque>
#include <string>
#include <vector>
#include <deque>
#include <boost/shared_ptr.hpp>

#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>

#include <Swiften/Base/API.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Base/Error.h>
#include <Swiften/Base/boost_bsignals.h>

namespace Swift {
class Connection;
Expand All @@ -26,6 +27,7 @@ namespace Swift {
class SWIFTEN_API ChainedConnector {
public:
ChainedConnector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver*, const std::vector<ConnectionFactory*>&, TimerFactory*);
~ChainedConnector();

void setTimeoutMilliseconds(int milliseconds);
void start();
Expand Down

0 comments on commit 6ca201d

Please sign in to comment.