From 4e21c065517d6e125cb1d1b9a13e886b3046b0d8 Mon Sep 17 00:00:00 2001 From: iphydf Date: Sat, 7 Jul 2018 22:15:08 +0000 Subject: 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 | 59 +++++++++++++++++++++++++++++++++++++++++++++++----------- toxcore/util.h | 12 +++++++++++- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/toxcore/util.c b/toxcore/util.c index aa2786dd..0bc77c05 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -36,33 +36,70 @@ #include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ #include "network.h" /* for current_time_monotonic */ +#include #include #include /* 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 Unix_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) +Unix_Time *unix_time_new(void) { - if (unix_base_time_value == 0) { - unix_base_time_value = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + Unix_Time *unixtime = (Unix_Time *)malloc(sizeof(Unix_Time)); + + if (unixtime == nullptr) { + return nullptr; } - unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value; + unixtime->time = 0; + unixtime->base_time = 0; + + return unixtime; } -uint64_t unix_time(void) +void unix_time_free(Unix_Time *unixtime) +{ + free(unixtime); +} + +void unix_time_update_r(Unix_Time *unixtime) +{ + if (unixtime->base_time == 0) { + unixtime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + } + + unixtime->time = (current_time_monotonic() / 1000ULL) + unixtime->base_time; +} + +uint64_t unix_time_get(const Unix_Time *unixtime) +{ + return unixtime->time; +} + +int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout) { - return unix_time_value; + return timestamp + timeout <= unix_time_get(unixtime); } +static Unix_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) +{ + unix_time_update_r(&global_time); +} +uint64_t unix_time(void) +{ + return unix_time_get(&global_time); +} int is_timeout(uint64_t timestamp, uint64_t timeout) { - return timestamp + timeout <= unix_time(); + return unix_time_is_timeout(&global_time, timestamp, timeout); } diff --git a/toxcore/util.h b/toxcore/util.h index c4d55f12..de493ebe 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -39,11 +39,21 @@ extern "C" { #define MIN(a,b) (((a)<(b))?(a):(b)) #define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } +typedef struct Unix_Time Unix_Time; + +Unix_Time *unix_time_new(void); +void unix_time_free(Unix_Time *unixtime); + +// TODO(#405): Use per-tox unixtime, remove unix_time_update, and rename +// unix_time_update_r to unix_time_update. +void unix_time_update_r(Unix_Time *unixtime); +uint64_t unix_time_get(const Unix_Time *unixtime); +int unix_time_is_timeout(const Unix_Time *unixtime, 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 */ -- cgit v1.2.3