From ad3345c77c117abfeba6119aae497e9e00cc213e Mon Sep 17 00:00:00 2001 From: iphydf Date: Sat, 7 Jul 2018 22:15:08 +0000 Subject: [PATCH] Add a thread-safe version of unix_time and friends. These are not used in a thread-safe way, but it opens the path towards per-tox-instance time keeping and removal of some unsafe global state. --- toxcore/util.c | 58 ++++++++++++++++++++++++++++++++++++++++---------- toxcore/util.h | 10 ++++++++- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/toxcore/util.c b/toxcore/util.c index 57d1762ee4e..9ec86843433 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -41,28 +41,64 @@ /* don't call into system billions of times for no reason */ -static uint64_t unix_time_value; -static uint64_t unix_base_time_value; +struct Mono_Time { + uint64_t time; + uint64_t base_time; +}; -/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of - * unix_time() may fail to increase monotonically with increasing time */ -void unix_time_update(void) +Mono_Time *mono_time_new(void) { - if (unix_base_time_value == 0) { - unix_base_time_value = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + Mono_Time *monotime = (Mono_Time *)malloc(sizeof(Mono_Time)); + + if (monotime == nullptr) { + return nullptr; } - unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value; + monotime->time = 0; + monotime->base_time = 0; + + return monotime; } -uint64_t unix_time(void) +void mono_time_free(Mono_Time *monotime) +{ + free(monotime); +} + +void mono_time_update(Mono_Time *monotime) +{ + if (monotime->base_time == 0) { + monotime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + } + + monotime->time = (current_time_monotonic() / 1000ULL) + monotime->base_time; +} + +uint64_t mono_time_get(const Mono_Time *monotime) +{ + return monotime->time; +} + +int mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout) { - return unix_time_value; + return timestamp + timeout <= mono_time_get(monotime); } +static Mono_Time global_time; + +/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of + * unix_time() may fail to increase monotonically with increasing time */ +void unix_time_update(void) +{ + return mono_time_update(&global_time); +} +uint64_t unix_time(void) +{ + return mono_time_get(&global_time); +} int is_timeout(uint64_t timestamp, uint64_t timeout) { - return timestamp + timeout <= unix_time(); + return mono_time_is_timeout(&global_time, timestamp, timeout); } diff --git a/toxcore/util.h b/toxcore/util.h index 3979cefee01..ae2dd2f297c 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -39,11 +39,19 @@ extern "C" { #define MIN(a,b) (((a)<(b))?(a):(b)) #define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } +typedef struct Mono_Time Mono_Time; + +Mono_Time *mono_time_new(void); +void mono_time_free(Mono_Time *monotime); + +void mono_time_update(Mono_Time *monotime); +uint64_t mono_time_get(const Mono_Time *monotime); +int mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout); + void unix_time_update(void); uint64_t unix_time(void); int is_timeout(uint64_t timestamp, uint64_t timeout); - /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src); uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */