diff options
author | Tobias Markmann <tm@ayena.de> | 2016-01-22 12:24:02 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2016-01-22 12:24:02 (GMT) |
commit | 52e685379436794cc0e4c2687c35f5e69a2f09a7 (patch) | |
tree | 8306420ffd1c9cd221545fb1382b13fc0496c6be | |
parent | 8480bdda831e4d18c1979f40badb1bc985e78865 (diff) | |
download | swift-52e685379436794cc0e4c2687c35f5e69a2f09a7.zip swift-52e685379436794cc0e4c2687c35f5e69a2f09a7.tar.bz2 |
Add missing Timer related cleanup code
This commit adds explicit code to stop timers which are
connected to objects that are about to be deleted from
memory.
Test-Information:
./scons test=system passes on OS X 10.11.3.
Change-Id: I139314f3a223e3dc63b78b96be17d3ae53cd3de3
-rw-r--r-- | SwifTools/Idle/ActualIdleDetector.cpp | 8 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.cpp | 7 | ||||
-rw-r--r-- | Swiften/FileTransfer/IncomingJingleFileTransfer.cpp | 6 | ||||
-rw-r--r-- | Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp | 7 |
4 files changed, 22 insertions, 6 deletions
diff --git a/SwifTools/Idle/ActualIdleDetector.cpp b/SwifTools/Idle/ActualIdleDetector.cpp index ba23b99..2e2f1f1 100644 --- a/SwifTools/Idle/ActualIdleDetector.cpp +++ b/SwifTools/Idle/ActualIdleDetector.cpp @@ -1,34 +1,36 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <SwifTools/Idle/ActualIdleDetector.h> + #include <boost/bind.hpp> -#include <iostream> -#include <SwifTools/Idle/IdleQuerier.h> #include <Swiften/Network/Timer.h> #include <Swiften/Network/TimerFactory.h> +#include <SwifTools/Idle/IdleQuerier.h> + namespace Swift { ActualIdleDetector::ActualIdleDetector(IdleQuerier* querier, TimerFactory* timerFactory, int refreshRateMilliseconds) : querier(querier) { timer = timerFactory->createTimer(refreshRateMilliseconds); timer->onTick.connect(boost::bind(&ActualIdleDetector::handleTimerTick, this)); timer->start(); } ActualIdleDetector::~ActualIdleDetector() { + timer->onTick.disconnect(boost::bind(&ActualIdleDetector::handleTimerTick, this)); timer->stop(); } void ActualIdleDetector::handleTimerTick() { timer->stop(); setIdle(querier->getIdleTimeSeconds() >= getIdleTimeSeconds()); timer->start(); } } diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index f4b715c..4a84a6e 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -27,92 +27,97 @@ #include <Swiften/Elements/MUCInvitationPayload.h> #include <Swiften/Elements/MUCUserPayload.h> #include <Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h> #include <Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h> #include <Swift/Controllers/Chat/ChatMessageParser.h> #include <Swift/Controllers/HighlightManager.h> #include <Swift/Controllers/Highlighter.h> #include <Swift/Controllers/Intl.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIInterfaces/ChatWindow.h> #include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h> #include <Swift/Controllers/XMPPEvents/EventController.h> #include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h> namespace Swift { ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory), entityCapsProvider_(entityCapsProvider), historyController_(historyController), mucRegistry_(mucRegistry), chatMessageParser_(chatMessageParser), autoAcceptMUCInviteDecider_(autoAcceptMUCInviteDecider), eventStream_(eventStream) { chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream); chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this)); chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2)); chatWindow_->onLogCleared.connect(boost::bind(&ChatControllerBase::handleLogCleared, this)); entityCapsProvider_->onCapsChanged.connect(boost::bind(&ChatControllerBase::handleCapsChanged, this, _1)); highlighter_ = highlightManager->createHighlighter(); ChatControllerBase::setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable()); createDayChangeTimer(); } ChatControllerBase::~ChatControllerBase() { + if (dateChangeTimer_) { + dateChangeTimer_->onTick.disconnect(boost::bind(&ChatControllerBase::handleDayChangeTick, this)); + dateChangeTimer_->stop(); + } + delete highlighter_; delete chatWindow_; } void ChatControllerBase::handleLogCleared() { cancelReplaces(); } ChatWindow* ChatControllerBase::detachChatWindow() { ChatWindow* chatWindow = chatWindow_; chatWindow_ = NULL; return chatWindow; } void ChatControllerBase::handleCapsChanged(const JID& jid) { if (jid.compare(toJID_, JID::WithoutResource) == 0) { handleBareJIDCapsChanged(jid); } } void ChatControllerBase::setCanStartImpromptuChats(bool supportsImpromptu) { if (chatWindow_) { chatWindow_->setCanInitiateImpromptuChats(supportsImpromptu); } } void ChatControllerBase::createDayChangeTimer() { if (timerFactory_) { boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); boost::posix_time::ptime midnight(now.date() + boost::gregorian::days(1)); int millisecondsUntilMidnight = boost::numeric_cast<int>((midnight - now).total_milliseconds()); - dateChangeTimer_ = boost::shared_ptr<Timer>(timerFactory_->createTimer(millisecondsUntilMidnight)); + dateChangeTimer_ = timerFactory_->createTimer(millisecondsUntilMidnight); dateChangeTimer_->onTick.connect(boost::bind(&ChatControllerBase::handleDayChangeTick, this)); dateChangeTimer_->start(); } } void ChatControllerBase::handleDayChangeTick() { dateChangeTimer_->stop(); boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10))), ChatWindow::DefaultDirection); dayTicked(); createDayChangeTimer(); } void ChatControllerBase::setEnabled(bool enabled) { chatWindow_->setOnline(enabled); chatWindow_->setCanInitiateImpromptuChats(false); } void ChatControllerBase::setOnline(bool online) { setEnabled(online); } JID ChatControllerBase::getBaseJID() { return JID(toJID_.toBare()); } void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabelsCatalogFeature)) { GetSecurityLabelsCatalogRequest::ref request = GetSecurityLabelsCatalogRequest::create(getBaseJID(), iqRouter_); request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2)); diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp index 01bed78..8cb1cab 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp @@ -1,88 +1,92 @@ /* - * Copyright (c) 2011-2015 Isode Limited. + * Copyright (c) 2011-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> #include <set> #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> #include <Swiften/Base/Log.h> #include <Swiften/Base/foreach.h> #include <Swiften/Elements/JingleFileTransferDescription.h> #include <Swiften/Elements/JingleFileTransferHash.h> #include <Swiften/Elements/JingleIBBTransportPayload.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/FileTransfer/FileTransferTransporter.h> #include <Swiften/FileTransfer/FileTransferTransporterFactory.h> #include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> #include <Swiften/FileTransfer/TransportSession.h> #include <Swiften/FileTransfer/WriteBytestream.h> #include <Swiften/Jingle/JingleSession.h> #include <Swiften/Network/TimerFactory.h> #include <Swiften/Queries/GenericRequest.h> #include <Swiften/StringCodecs/Base64.h> using namespace Swift; // TODO: ALlow terminate when already terminated. IncomingJingleFileTransfer::IncomingJingleFileTransfer( const JID& toJID, JingleSession::ref session, JingleContentPayload::ref content, FileTransferTransporterFactory* transporterFactory, TimerFactory* timerFactory, CryptoProvider* crypto) : JingleFileTransfer(session, toJID, transporterFactory), initialContent(content), crypto(crypto), state(Initial), receivedBytes(0), hashCalculator(NULL) { description = initialContent->getDescription<JingleFileTransferDescription>(); assert(description); JingleFileTransferFileInfo fileInfo = description->getFileInfo(); setFileInfo(fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription()); hashes = fileInfo.getHashes(); waitOnHashTimer = timerFactory->createTimer(5000); waitOnHashTimerTickedConnection = waitOnHashTimer->onTick.connect( boost::bind(&IncomingJingleFileTransfer::handleWaitOnHashTimerTicked, this)); } IncomingJingleFileTransfer::~IncomingJingleFileTransfer() { + if (waitOnHashTimer) { + waitOnHashTimer->stop(); + } + delete hashCalculator; hashCalculator = NULL; } void IncomingJingleFileTransfer::accept( boost::shared_ptr<WriteBytestream> stream, const FileTransferOptions& options) { SWIFT_LOG(debug) << std::endl; if (state != Initial) { SWIFT_LOG(warning) << "Incorrect state" << std::endl; return; } assert(!this->stream); this->stream = stream; this->options = options; assert(!hashCalculator); hashCalculator = new IncrementalBytestreamHashCalculator( hashes.find("md5") != hashes.end(), hashes.find("sha-1") != hashes.end(), crypto); writeStreamDataReceivedConnection = stream->onWrite.connect( boost::bind(&IncomingJingleFileTransfer::handleWriteStreamDataReceived, this, _1)); if (JingleS5BTransportPayload::ref s5bTransport = initialContent->getTransport<JingleS5BTransportPayload>()) { SWIFT_LOG(debug) << "Got S5B transport as initial payload." << std::endl; setTransporter(transporterFactory->createResponderTransporter( getInitiator(), getResponder(), s5bTransport->getSessionID(), options)); transporter->addRemoteCandidates(s5bTransport->getCandidates(), s5bTransport->getDstAddr()); setState(GeneratingInitialLocalCandidates); transporter->startGeneratingLocalCandidates(); } diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp index b8e848c..a72d5ef 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp @@ -1,38 +1,38 @@ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2013-2015 Isode Limited. + * Copyright (c) 2013-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ // TODO: // - We should handle incoming terminates after we have terminated, so the other // side can warn that he didn't receive all bytes correctly. // - Should the proby stuff also wait for candidate used acknowledgement? #include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h> #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> #include <boost/typeof/typeof.hpp> #include <Swiften/Base/IDGenerator.h> #include <Swiften/Base/Log.h> #include <Swiften/Base/foreach.h> #include <Swiften/Crypto/CryptoProvider.h> #include <Swiften/Elements/JingleFileTransferDescription.h> #include <Swiften/Elements/JingleFileTransferHash.h> #include <Swiften/Elements/JingleIBBTransportPayload.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/Elements/JingleTransportPayload.h> #include <Swiften/FileTransfer/FileTransferTransporter.h> #include <Swiften/FileTransfer/FileTransferTransporterFactory.h> #include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> #include <Swiften/FileTransfer/ReadBytestream.h> #include <Swiften/FileTransfer/TransportSession.h> #include <Swiften/Jingle/JingleContentID.h> @@ -47,60 +47,65 @@ OutgoingJingleFileTransfer::OutgoingJingleFileTransfer( const JID& toJID, JingleSession::ref session, boost::shared_ptr<ReadBytestream> stream, FileTransferTransporterFactory* transporterFactory, TimerFactory* timerFactory, IDGenerator* idGenerator, const JingleFileTransferFileInfo& fileInfo, const FileTransferOptions& options, CryptoProvider* crypto) : JingleFileTransfer(session, toJID, transporterFactory), idGenerator(idGenerator), stream(stream), fileInfo(fileInfo), options(options), contentID(idGenerator->generateID(), JingleContentPayload::InitiatorCreator), state(Initial), candidateAcknowledged(false) { setFileInfo(fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription()); // calculate both, MD5 and SHA-1 since we don't know which one the other side supports hashCalculator = new IncrementalBytestreamHashCalculator(true, true, crypto); stream->onRead.connect( boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); waitForRemoteTermination = timerFactory->createTimer(5000); waitForRemoteTermination->onTick.connect(boost::bind(&OutgoingJingleFileTransfer::handleWaitForRemoteTerminationTimeout, this)); } OutgoingJingleFileTransfer::~OutgoingJingleFileTransfer() { + if (waitForRemoteTermination) { + waitForRemoteTermination->onTick.disconnect(boost::bind(&OutgoingJingleFileTransfer::handleWaitForRemoteTerminationTimeout, this)); + waitForRemoteTermination->stop(); + } + stream->onRead.disconnect( boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); delete hashCalculator; hashCalculator = NULL; removeTransporter(); } void OutgoingJingleFileTransfer::start() { SWIFT_LOG(debug) << std::endl; if (state != Initial) { SWIFT_LOG(warning) << "Incorrect state" << std::endl; return; } setTransporter(transporterFactory->createInitiatorTransporter(getInitiator(), getResponder(), options)); setInternalState(GeneratingInitialLocalCandidates); transporter->startGeneratingLocalCandidates(); } void OutgoingJingleFileTransfer::cancel() { terminate(JinglePayload::Reason::Cancel); } void OutgoingJingleFileTransfer::terminate(JinglePayload::Reason::Type reason) { SWIFT_LOG(debug) << reason << std::endl; if (state != Initial && state != GeneratingInitialLocalCandidates && state != Finished) { session->sendTerminate(reason); } stopAll(); |