summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Network/ChainedConnector.cpp')
-rw-r--r--Swiften/Network/ChainedConnector.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/Swiften/Network/ChainedConnector.cpp b/Swiften/Network/ChainedConnector.cpp
new file mode 100644
index 0000000..1a38e53
--- /dev/null
+++ b/Swiften/Network/ChainedConnector.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Network/ChainedConnector.h>
+
+#include <boost/bind.hpp>
+#include <typeinfo>
+
+#include <Swiften/Base/Log.h>
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Network/Connector.h>
+#include <Swiften/Network/ConnectionFactory.h>
+
+using namespace Swift;
+
+ChainedConnector::ChainedConnector(
+ const std::string& hostname,
+ DomainNameResolver* resolver,
+ const std::vector<ConnectionFactory*>& connectionFactories,
+ TimerFactory* timerFactory) :
+ hostname(hostname),
+ resolver(resolver),
+ connectionFactories(connectionFactories),
+ timerFactory(timerFactory),
+ timeoutMilliseconds(0) {
+}
+
+void ChainedConnector::setTimeoutMilliseconds(int milliseconds) {
+ timeoutMilliseconds = milliseconds;
+}
+
+void ChainedConnector::start() {
+ SWIFT_LOG(debug) << "Starting queued connector for " << hostname << std::endl;
+
+ connectionFactoryQueue = std::deque<ConnectionFactory*>(connectionFactories.begin(), connectionFactories.end());
+ tryNextConnectionFactory();
+}
+
+void ChainedConnector::stop() {
+ if (currentConnector) {
+ currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1));
+ currentConnector->stop();
+ currentConnector.reset();
+ }
+ finish(boost::shared_ptr<Connection>());
+}
+
+void ChainedConnector::tryNextConnectionFactory() {
+ assert(!currentConnector);
+ if (connectionFactoryQueue.empty()) {
+ SWIFT_LOG(debug) << "No more connection factories" << std::endl;
+ finish(boost::shared_ptr<Connection>());
+ }
+ else {
+ ConnectionFactory* connectionFactory = connectionFactoryQueue.front();
+ SWIFT_LOG(debug) << "Trying next connection factory: " << typeid(*connectionFactory).name() << std::endl;
+ connectionFactoryQueue.pop_front();
+ currentConnector = Connector::create(hostname, resolver, connectionFactory, timerFactory);
+ currentConnector->setTimeoutMilliseconds(timeoutMilliseconds);
+ currentConnector->onConnectFinished.connect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1));
+ currentConnector->start();
+ }
+}
+
+void ChainedConnector::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
+ SWIFT_LOG(debug) << "Connector finished" << std::endl;
+ currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1));
+ currentConnector.reset();
+ if (connection) {
+ finish(connection);
+ }
+ else {
+ tryNextConnectionFactory();
+ }
+}
+
+void ChainedConnector::finish(boost::shared_ptr<Connection> connection) {
+ onConnectFinished(connection);
+}