From 8b30e312bbc0728b527941d5b0a6d0f621025ed0 Mon Sep 17 00:00:00 2001
From: Florent Le Coz <louiz@louiz.org>
Date: Sun, 8 Jun 2014 15:13:08 +0200
Subject: Add a TimedEvent to cancel the connection to a server after 5 seconds

---
 src/network/socket_handler.cpp | 18 ++++++++++++++++++
 src/network/socket_handler.hpp |  5 +++++
 2 files changed, 23 insertions(+)

(limited to 'src')

diff --git a/src/network/socket_handler.cpp b/src/network/socket_handler.cpp
index d989623..a2c22e4 100644
--- a/src/network/socket_handler.cpp
+++ b/src/network/socket_handler.cpp
@@ -1,5 +1,6 @@
 #include <network/socket_handler.hpp>
 
+#include <utils/timed_events.hpp>
 #include <utils/scopeguard.hpp>
 #include <network/poller.hpp>
 
@@ -26,6 +27,7 @@
 #endif
 
 using namespace std::string_literals;
+using namespace std::chrono_literals;
 
 namespace ph = std::placeholders;
 
@@ -117,6 +119,8 @@ void SocketHandler::connect(const std::string& address, const std::string& port,
           || errno == EISCONN)
         {
           log_info("Connection success.");
+          TimedEventsManager::instance().cancel("connection_timeout"s +
+                                                std::to_string(this->socket));
           this->poller->add_socket_handler(this);
           this->connected = true;
           this->connecting = false;
@@ -139,6 +143,12 @@ void SocketHandler::connect(const std::string& address, const std::string& port,
           memcpy(&this->addrinfo, rp, sizeof(struct addrinfo));
           this->addrinfo.ai_addr = &this->ai_addr;
           this->addrinfo.ai_next = nullptr;
+          // If the connection has not succeeded or failed in 5s, we consider
+          // it to have failed
+          TimedEventsManager::instance().add_event(
+                TimedEvent(std::chrono::steady_clock::now() + 5s,
+                           std::bind(&SocketHandler::on_connection_timeout, this),
+                           "connection_timeout"s + std::to_string(this->socket)));
           return ;
         }
       log_info("Connection failed:" << strerror(errno));
@@ -149,6 +159,12 @@ void SocketHandler::connect(const std::string& address, const std::string& port,
   return ;
 }
 
+void SocketHandler::on_connection_timeout()
+{
+  this->close();
+  this->on_connection_failed("connection timed out");
+}
+
 void SocketHandler::connect()
 {
   this->connect(this->address, this->port, this->use_tls);
@@ -273,6 +289,8 @@ void SocketHandler::close()
   this->in_buf.clear();
   this->out_buf.clear();
   this->port.clear();
+  TimedEventsManager::instance().cancel("connection_timeout"s +
+                                        std::to_string(this->socket));
 }
 
 socket_t SocketHandler::get_socket() const
diff --git a/src/network/socket_handler.hpp b/src/network/socket_handler.hpp
index 02311c4..95e38bd 100644
--- a/src/network/socket_handler.hpp
+++ b/src/network/socket_handler.hpp
@@ -85,6 +85,11 @@ public:
    * Close the connection, remove us from the poller
    */
   void close();
+  /**
+   * Called by a TimedEvent, when the connection did not succeed or fail
+   * after a given time.
+   */
+  void on_connection_timeout();
   /**
    * Called when the connection is successful.
    */
-- 
cgit v1.2.3