Commit 5f0265920d4b80565fe3c8a83763cfc483e5efb8

Authored by Wiebe Cazemier
1 parent de87724a

Use monotonic clock for keep alive mechanism

client.cpp
... ... @@ -21,6 +21,7 @@ License along with FlashMQ. If not, see <https://www.gnu.org/licenses/>.
21 21 #include <sstream>
22 22 #include <iostream>
23 23 #include <cassert>
  24 +#include <chrono>
24 25  
25 26 #include "logger.h"
26 27  
... ... @@ -136,7 +137,7 @@ bool Client::readFdIntoBuffer()
136 137 return false;
137 138 }
138 139  
139   - lastActivity = time(NULL);
  140 + lastActivity = std::chrono::steady_clock::now();
140 141 if (session)
141 142 session->touch(lastActivity);
142 143  
... ... @@ -273,17 +274,22 @@ bool Client::keepAliveExpired()
273 274 if (keepalive == 0)
274 275 return false;
275 276  
  277 + const std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
  278 +
276 279 if (!authenticated)
277   - return lastActivity + 20 < time(NULL);
  280 + return lastActivity + std::chrono::seconds(20) < now;
278 281  
279   - bool result = (lastActivity + (keepalive*10/5)) < time(NULL);
  282 + std::chrono::seconds x(keepalive*10/5);
  283 + bool result = (lastActivity + x) < now;
280 284 return result;
281 285 }
282 286  
283 287 std::string Client::getKeepAliveInfoString() const
284 288 {
285   - std::string s = "authenticated: " + std::to_string(authenticated) + ", keep-alive: " + std::to_string(keepalive) + "s, last activity "
286   - + std::to_string(time(NULL) - lastActivity) + " seconds ago.";
  289 + std::chrono::seconds secondsSinceLastActivity = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - lastActivity);
  290 +
  291 + std::string s = formatString("authenticated=%s, keep-alive=%ss, last activity=%s seconds ago.", std::to_string(authenticated).c_str(), std::to_string(keepalive).c_str(),
  292 + std::to_string(secondsSinceLastActivity.count()).c_str());
287 293 return s;
288 294 }
289 295  
... ...
client.h
... ... @@ -65,7 +65,7 @@ class Client
65 65 bool disconnectWhenBytesWritten = false;
66 66 bool disconnecting = false;
67 67 std::string disconnectReason;
68   - time_t lastActivity = time(NULL);
  68 + std::chrono::time_point<std::chrono::steady_clock> lastActivity;
69 69  
70 70 std::string clientid;
71 71 std::string username;
... ...
session.cpp
... ... @@ -164,15 +164,19 @@ uint64_t Session::sendPendingQosMessages()
164 164 return count;
165 165 }
166 166  
167   -void Session::touch(time_t val)
  167 +std::chrono::time_point<std::chrono::steady_clock> zeroTime;
  168 +std::chrono::seconds expireAfter(EXPIRE_SESSION_AFTER);
  169 +
  170 +void Session::touch(std::chrono::time_point<std::chrono::steady_clock> val)
168 171 {
169   - time_t newval = val > 0 ? val : time(NULL);
  172 + std::chrono::time_point<std::chrono::steady_clock> newval = val > zeroTime ? val : std::chrono::steady_clock::now();
170 173 lastTouched = newval;
171 174 }
172 175  
173 176 bool Session::hasExpired()
174 177 {
175   - return clientDisconnected() && (lastTouched + EXPIRE_SESSION_AFTER) < time(NULL);
  178 + std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
  179 + return clientDisconnected() && (lastTouched + expireAfter) < now;
176 180 }
177 181  
178 182 void Session::addIncomingQoS2MessageId(uint16_t packet_id)
... ...
session.h
... ... @@ -51,7 +51,7 @@ class Session
51 51 std::mutex qosQueueMutex;
52 52 uint16_t nextPacketId = 0;
53 53 ssize_t qosQueueBytes = 0;
54   - time_t lastTouched = time(NULL);
  54 + std::chrono::time_point<std::chrono::steady_clock> lastTouched;
55 55 Logger *logger = Logger::getInstance();
56 56  
57 57 public:
... ... @@ -67,7 +67,7 @@ public:
67 67 void writePacket(const MqttPacket &packet, char max_qos, uint64_t &count);
68 68 void clearQosMessage(uint16_t packet_id);
69 69 uint64_t sendPendingQosMessages();
70   - void touch(time_t val = 0);
  70 + void touch(std::chrono::time_point<std::chrono::steady_clock> val = std::chrono::time_point<std::chrono::steady_clock>());
71 71 bool hasExpired();
72 72  
73 73 void addIncomingQoS2MessageId(uint16_t packet_id);
... ...