summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2016-01-22 12:24:02 (GMT)
committerTobias Markmann <tm@ayena.de>2016-01-22 12:24:02 (GMT)
commit52e685379436794cc0e4c2687c35f5e69a2f09a7 (patch)
tree8306420ffd1c9cd221545fb1382b13fc0496c6be
parent8480bdda831e4d18c1979f40badb1bc985e78865 (diff)
downloadswift-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.cpp8
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp7
-rw-r--r--Swiften/FileTransfer/IncomingJingleFileTransfer.cpp6
-rw-r--r--Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp7
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();