From da7baf5313c35b87f39ee8394eac6cecaa328772 Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Sat, 25 May 2019 21:33:53 +0200 Subject: [PATCH] ServerUser: use QTime instead of std::chrono and ctime The legacy implementation (with ctime), used when std::chrono is not available (C++ < 11), caused the client's messages to be permanently blocked until it reconnected. More specifically, millisecondsBetween() always returned 0. This commit replaces both implementations with a simpler one which makes use of QTime. --- src/murmur/ServerUser.cpp | 32 +++++++------------------------- src/murmur/ServerUser.h | 16 ++-------------- 2 files changed, 9 insertions(+), 39 deletions(-) diff --git a/src/murmur/ServerUser.cpp b/src/murmur/ServerUser.cpp index 18db498e5..121b75c0b 100644 --- a/src/murmur/ServerUser.cpp +++ b/src/murmur/ServerUser.cpp @@ -112,32 +112,14 @@ int BandwidthRecord::bandwidth() const { return static_cast((sum * 1000000ULL) / elapsed); } -#if __cplusplus > 199711LL - -inline static -time_point now() { - return std::chrono::steady_clock::now(); +inline static QTime now() { + return QTime::currentTime(); } -inline static -unsigned long millisecondsBetween(time_point start, time_point end) { - return std::chrono::duration_cast(end - start).count(); +inline static int millisecondsBetween(const QTime &start, const QTime &end) { + return start.msecsTo(end); } -#else - -inline static -time_point now() { - return clock(); -} - -inline static -unsigned long millisecondsBetween(time_point start, time_point end) { - return 1000 * (end - start) / CLOCKS_PER_SEC; -} - -#endif - // Rate limiting: burst up to 5, 1 message per sec limit over longer time LeakyBucket::LeakyBucket(unsigned int tokensPerSec, unsigned int maxTokens) : tokensPerSec(tokensPerSec), maxTokens(maxTokens), currentTokens(0) { lastUpdate = now(); @@ -145,10 +127,10 @@ LeakyBucket::LeakyBucket(unsigned int tokensPerSec, unsigned int maxTokens) : to bool LeakyBucket::ratelimit(int tokens) { // First remove tokens we leaked over time - time_point tnow = now(); - long ms = millisecondsBetween(lastUpdate, tnow); + const QTime tnow = now(); + const long ms = millisecondsBetween(lastUpdate, tnow); - long drainTokens = (ms * tokensPerSec) / 1000; + const long drainTokens = (ms * tokensPerSec) / 1000; // Prevent constant starvation due to too many updates if (drainTokens > 0) { diff --git a/src/murmur/ServerUser.h b/src/murmur/ServerUser.h index 36ba8d8da..09dee4dcb 100644 --- a/src/murmur/ServerUser.h +++ b/src/murmur/ServerUser.h @@ -7,6 +7,7 @@ #define MUMBLE_MURMUR_SERVERUSER_H_ #include +#include #ifdef Q_OS_UNIX #include @@ -14,13 +15,6 @@ #include #endif -// was introduced in C++11 -#if __cplusplus > 199711LL -#include -#else -#include -#endif - #include "Connection.h" #include "Timer.h" #include "User.h" @@ -62,18 +56,12 @@ struct WhisperTarget { class Server; -#if __cplusplus > 199711L - typedef std::chrono::time_point time_point; -#else - typedef clock_t time_point; -#endif - // Simple algorithm for rate limiting class LeakyBucket { private: unsigned int tokensPerSec, maxTokens; long currentTokens; - time_point lastUpdate; + QTime lastUpdate; public: // Returns true if packets should be dropped