summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-10-10 07:37:12 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-10-10 07:46:36 (GMT)
commit150542a5c60fe49f4e164ffdaa51236795426214 (patch)
tree238eda2d89e8347e32d2eabc224633c518fe5083
parentf9187481a14493a729987ebbcfd10839b2439b96 (diff)
downloadswift-150542a5c60fe49f4e164ffdaa51236795426214.zip
swift-150542a5c60fe49f4e164ffdaa51236795426214.tar.bz2
Force disconnect signals when calling connect() shortly after disconnect().
-rw-r--r--Swiften/Client/CoreClient.cpp57
-rw-r--r--Swiften/Client/CoreClient.h4
-rw-r--r--Swiften/QA/ClientTest/ClientTest.cpp34
3 files changed, 62 insertions, 33 deletions
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index dbc6de2..22e3612 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -41,9 +41,7 @@ CoreClient::CoreClient(const JID& jid, const SafeByteArray& password, NetworkFac
}
CoreClient::~CoreClient() {
- if ((session_ && !session_->isFinished()) || connection_) {
- std::cerr << "Warning: Client not disconnected properly" << std::endl;
- }
+ forceReset();
delete tlsFactories;
delete iqRouter_;
@@ -61,10 +59,11 @@ void CoreClient::connect(const ClientOptions& o) {
}
void CoreClient::connect(const std::string& host) {
+ forceReset();
+
SWIFT_LOG(debug) << "Connecting to host " << host << std::endl;
disconnectRequested_ = false;
assert(!connector_);
-
assert(proxyConnectionFactories.empty());
PlatformProxyProvider proxyProvider;
if(proxyProvider.getSOCKS5Proxy().isValid()) {
@@ -83,13 +82,7 @@ void CoreClient::connect(const std::string& host) {
}
void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
- connector_->onConnectFinished.disconnect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));
- connector_.reset();
- foreach(ConnectionFactory* f, proxyConnectionFactories) {
- delete f;
- }
- proxyConnectionFactories.clear();
-
+ resetConnector();
if (!connection) {
if (options.forgetPassword) {
purgePassword();
@@ -151,15 +144,7 @@ void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) {
if (options.forgetPassword) {
purgePassword();
}
- session_->onFinished.disconnect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
- session_->onNeedCredentials.disconnect(boost::bind(&CoreClient::handleNeedCredentials, this));
-
- sessionStream_->onDataRead.disconnect(boost::bind(&CoreClient::handleDataRead, this, _1));
- sessionStream_->onDataWritten.disconnect(boost::bind(&CoreClient::handleDataWritten, this, _1));
- sessionStream_.reset();
-
- connection_->disconnect();
- connection_.reset();
+ resetSession();
boost::optional<ClientError> actualError;
if (error) {
@@ -341,4 +326,36 @@ void CoreClient::purgePassword() {
safeClear(password_);
}
+void CoreClient::resetConnector() {
+ connector_->onConnectFinished.disconnect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));
+ connector_.reset();
+ foreach(ConnectionFactory* f, proxyConnectionFactories) {
+ delete f;
+ }
+ proxyConnectionFactories.clear();
+}
+
+void CoreClient::resetSession() {
+ session_->onFinished.disconnect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
+ session_->onNeedCredentials.disconnect(boost::bind(&CoreClient::handleNeedCredentials, this));
+
+ sessionStream_->onDataRead.disconnect(boost::bind(&CoreClient::handleDataRead, this, _1));
+ sessionStream_->onDataWritten.disconnect(boost::bind(&CoreClient::handleDataWritten, this, _1));
+ sessionStream_.reset();
+
+ connection_->disconnect();
+ connection_.reset();
+}
+
+void CoreClient::forceReset() {
+ if (connector_) {
+ std::cerr << "Warning: Client not disconnected properly: Connector still active" << std::endl;
+ resetConnector();
+ }
+ if (sessionStream_ || connection_) {
+ std::cerr << "Warning: Client not disconnected properly: Session still active" << std::endl;
+ resetSession();
+ }
+}
+
}
diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h
index 3472e76..ad31e72 100644
--- a/Swiften/Client/CoreClient.h
+++ b/Swiften/Client/CoreClient.h
@@ -209,6 +209,10 @@ namespace Swift {
void handleStanzaAcked(boost::shared_ptr<Stanza>);
void purgePassword();
+ void resetConnector();
+ void resetSession();
+ void forceReset();
+
private:
JID jid_;
SafeByteArray password_;
diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp
index 584f644..4515893 100644
--- a/Swiften/QA/ClientTest/ClientTest.cpp
+++ b/Swiften/QA/ClientTest/ClientTest.cpp
@@ -22,27 +22,33 @@ SimpleEventLoop eventLoop;
BoostNetworkFactories networkFactories(&eventLoop);
Client* client = 0;
-bool reconnected = false;
bool rosterReceived = false;
+enum TestStage {
+ FirstConnect,
+ Reconnect
+};
+TestStage stage;
-void handleDisconnected(boost::optional<ClientError>) {
- eventLoop.stop();
-}
-
-void handleRosterReceived(boost::shared_ptr<Payload>) {
- if (reconnected) {
- rosterReceived = true;
- client->onDisconnected.connect(boost::bind(&handleDisconnected, _1));
- client->disconnect();
+void handleDisconnected(boost::optional<ClientError> e) {
+ std::cout << "Disconnected: " << e << std::endl;
+ if (stage == FirstConnect) {
+ stage = Reconnect;
+ client->connect();
}
else {
- reconnected = true;
- client->disconnect();
- client->connect();
+ eventLoop.stop();
}
}
+void handleRosterReceived(boost::shared_ptr<Payload>) {
+ rosterReceived = true;
+ std::cout << "Disconnecting" << std::endl;
+ client->disconnect();
+}
+
void handleConnected() {
+ std::cout << "Connected" << std::endl;
+ rosterReceived = false;
GetRosterRequest::ref rosterRequest = GetRosterRequest::create(client->getIQRouter());
rosterRequest->onResponse.connect(boost::bind(&handleRosterReceived, _1));
rosterRequest->send();
@@ -63,7 +69,9 @@ int main(int, char**) {
client = new Swift::Client(JID(jid), std::string(pass), &networkFactories);
ClientXMLTracer* tracer = new ClientXMLTracer(client);
client->onConnected.connect(&handleConnected);
+ client->onDisconnected.connect(boost::bind(&handleDisconnected, _1));
client->setAlwaysTrustCertificates();
+ stage = FirstConnect;
client->connect();
{