summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Client/Client.cpp')
-rw-r--r--Swiften/Client/Client.cpp62
1 files changed, 32 insertions, 30 deletions
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 974e256..5b57672 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -21,7 +21,7 @@
namespace Swift {
-Client::Client(const JID& jid, const String& password) : jid_(jid), password_(password) {
+Client::Client(const JID& jid, const String& password) : jid_(jid), password_(password), disconnectRequested_(false) {
iqRouter_ = new IQRouter(this);
connectionFactory_ = new BoostConnectionFactory(&MainBoostIOServiceThread::getInstance().getIOService());
timerFactory_ = new BoostTimerFactory(&MainBoostIOServiceThread::getInstance().getIOService());
@@ -52,26 +52,20 @@ void Client::connect(const JID& jid) {
}
void Client::connect(const String& host) {
- assert(!connector_); // Crash on reconnect is here.
+ assert(!connector_);
connector_ = Connector::create(host, &resolver_, connectionFactory_, timerFactory_);
- connector_->onConnectFinished.connect(boost::bind(&Client::handleConnectorFinished, this, _1, connector_));
+ connector_->onConnectFinished.connect(boost::bind(&Client::handleConnectorFinished, this, _1));
connector_->setTimeoutMilliseconds(60*1000);
connector_->start();
}
-void Client::handleConnectorFinished(boost::shared_ptr<Connection> connection, Connector::ref connector) {
- bool currentConnection = connector_ && (connector.get() == connector_.get());
- // TODO: Add domain name resolver error
- if (!currentConnection) {
- /* disconnect() was called, this connection should be thrown away*/
- if (connection) {
- connection->disconnect();
- }
- return;
- }
+void Client::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
+ connector_->onConnectFinished.disconnect(boost::bind(&Client::handleConnectorFinished, this, _1));
connector_.reset();
if (!connection) {
- onError(ClientError::ConnectionError);
+ if (!disconnectRequested_) {
+ onError(ClientError::ConnectionError);
+ }
}
else {
assert(!connection_);
@@ -97,25 +91,20 @@ void Client::handleConnectorFinished(boost::shared_ptr<Connection> connection, C
}
void Client::disconnect() {
- if (connector_) {
- connector_.reset();
- }
+ // FIXME: We should be able to do without this boolean. We just have to make sure we can tell the difference between
+ // connector finishing without a connection due to an error or because of a disconnect.
+ disconnectRequested_ = true;
if (session_) {
session_->finish();
}
- else {
- closeConnection();
- }
-}
-
-void Client::closeConnection() {
- if (sessionStream_) {
- sessionStream_.reset();
- }
- if (connection_) {
- connection_->disconnect();
- connection_.reset();
+ else if (connector_) {
+ connector_->stop();
+ assert(!session_);
}
+ assert(!session_);
+ assert(!sessionStream_);
+ assert(!connector_);
+ disconnectRequested_ = false;
}
void Client::send(boost::shared_ptr<Stanza> stanza) {
@@ -167,9 +156,22 @@ void Client::setCertificate(const String& certificate) {
}
void Client::handleSessionFinished(boost::shared_ptr<Error> error) {
+ session_->onInitialized.disconnect(boost::bind(&Client::handleSessionInitialized, this));
+ session_->onStanzaAcked.disconnect(boost::bind(&Client::handleStanzaAcked, this, _1));
+ session_->onFinished.disconnect(boost::bind(&Client::handleSessionFinished, this, _1));
+ session_->onNeedCredentials.disconnect(boost::bind(&Client::handleNeedCredentials, this));
+ session_->onStanzaReceived.disconnect(boost::bind(&Client::handleStanza, this, _1));
session_.reset();
- closeConnection();
+
+ sessionStream_->onDataRead.disconnect(boost::bind(&Client::handleDataRead, this, _1));
+ sessionStream_->onDataWritten.disconnect(boost::bind(&Client::handleDataWritten, this, _1));
+ sessionStream_.reset();
+
+ connection_->disconnect();
+ connection_.reset();
+
onAvailableChanged(false);
+
if (error) {
ClientError clientError;
if (boost::shared_ptr<ClientSession::Error> actualError = boost::dynamic_pointer_cast<ClientSession::Error>(error)) {