Fix timeout behavior with persistent connections.
[cubemap] / server.cpp
index ccac946..78273b0 100644 (file)
@@ -210,16 +210,7 @@ void Server::add_client(int sock, Acceptor *acceptor)
        assert(inserted.second == true);  // Should not already exist.
        Client *client_ptr = &inserted.first->second;
 
-       // Connection timestamps must be nondecreasing. I can't find any guarantee
-       // that even the monotonic clock can't go backwards by a small amount
-       // (think switching between CPUs with non-synchronized TSCs), so if
-       // this actually should happen, we hack around it by fudging
-       // connect_time.
-       if (!clients_ordered_by_connect_time.empty() &&
-           is_earlier(client_ptr->connect_time, clients_ordered_by_connect_time.back().first)) {
-               client_ptr->connect_time = clients_ordered_by_connect_time.back().first;
-       }
-       clients_ordered_by_connect_time.push(make_pair(client_ptr->connect_time, sock));
+       start_client_timeout_timer(client_ptr);
 
        // Start listening on data from this socket.
        epoll_event ev;
@@ -302,6 +293,24 @@ void Server::add_client_from_serialized(const ClientProto &client, const vector<
        }
 }
 
+void Server::start_client_timeout_timer(Client *client)
+{
+       // Connection timestamps must be nondecreasing. I can't find any guarantee
+       // that even the monotonic clock can't go backwards by a small amount
+       // (think switching between CPUs with non-synchronized TSCs), so if
+       // this actually should happen, we hack around it by fudging
+       // connect_time.
+       if (clock_gettime(CLOCK_MONOTONIC_COARSE, &client->connect_time) == -1) {
+               log_perror("clock_gettime(CLOCK_MONOTONIC_COARSE)");
+       } else {
+               if (!clients_ordered_by_connect_time.empty() &&
+                   is_earlier(client->connect_time, clients_ordered_by_connect_time.back().first)) {
+                       client->connect_time = clients_ordered_by_connect_time.back().first;
+               }
+               clients_ordered_by_connect_time.push(make_pair(client->connect_time, client->sock));
+       }
+}
+
 int Server::lookup_stream_by_url(const string &url) const
 {
        const auto stream_url_it = stream_url_map.find(url);
@@ -1323,6 +1332,7 @@ bool Server::more_requests(Client *client)
        client->header_or_short_response_holder.clear();
        client->header_or_short_response_ref.reset();
        client->header_or_short_response_bytes_sent = 0;
+       start_client_timeout_timer(client);
 
        change_epoll_events(client, EPOLLIN | EPOLLET | EPOLLRDHUP);  // No TLS handshake, so no EPOLLOUT needed.