diff options
author | iphydf <iphydf@users.noreply.github.com> | 2018-07-07 22:15:08 +0000 |
---|---|---|
committer | iphydf <iphydf@users.noreply.github.com> | 2018-07-09 21:03:08 +0000 |
commit | 4e21c065517d6e125cb1d1b9a13e886b3046b0d8 (patch) | |
tree | ec075cedb1d084867acd213c10bed2974d0b3039 /toxcore/util.c | |
parent | c8697ccc20e12b0f4a2394c10f01ce147eeca269 (diff) |
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.
Diffstat (limited to 'toxcore/util.c')
-rw-r--r-- | toxcore/util.c | 59 |
1 files changed, 48 insertions, 11 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 @@ | |||
36 | #include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ | 36 | #include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ |
37 | #include "network.h" /* for current_time_monotonic */ | 37 | #include "network.h" /* for current_time_monotonic */ |
38 | 38 | ||
39 | #include <stdlib.h> | ||
39 | #include <string.h> | 40 | #include <string.h> |
40 | #include <time.h> | 41 | #include <time.h> |
41 | 42 | ||
42 | 43 | ||
43 | /* don't call into system billions of times for no reason */ | 44 | /* don't call into system billions of times for no reason */ |
44 | static uint64_t unix_time_value; | 45 | struct Unix_Time { |
45 | static uint64_t unix_base_time_value; | 46 | uint64_t time; |
47 | uint64_t base_time; | ||
48 | }; | ||
46 | 49 | ||
47 | /* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of | 50 | Unix_Time *unix_time_new(void) |
48 | * unix_time() may fail to increase monotonically with increasing time */ | ||
49 | void unix_time_update(void) | ||
50 | { | 51 | { |
51 | if (unix_base_time_value == 0) { | 52 | Unix_Time *unixtime = (Unix_Time *)malloc(sizeof(Unix_Time)); |
52 | unix_base_time_value = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); | 53 | |
54 | if (unixtime == nullptr) { | ||
55 | return nullptr; | ||
53 | } | 56 | } |
54 | 57 | ||
55 | unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value; | 58 | unixtime->time = 0; |
59 | unixtime->base_time = 0; | ||
60 | |||
61 | return unixtime; | ||
56 | } | 62 | } |
57 | 63 | ||
58 | uint64_t unix_time(void) | 64 | void unix_time_free(Unix_Time *unixtime) |
65 | { | ||
66 | free(unixtime); | ||
67 | } | ||
68 | |||
69 | void unix_time_update_r(Unix_Time *unixtime) | ||
70 | { | ||
71 | if (unixtime->base_time == 0) { | ||
72 | unixtime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); | ||
73 | } | ||
74 | |||
75 | unixtime->time = (current_time_monotonic() / 1000ULL) + unixtime->base_time; | ||
76 | } | ||
77 | |||
78 | uint64_t unix_time_get(const Unix_Time *unixtime) | ||
79 | { | ||
80 | return unixtime->time; | ||
81 | } | ||
82 | |||
83 | int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout) | ||
59 | { | 84 | { |
60 | return unix_time_value; | 85 | return timestamp + timeout <= unix_time_get(unixtime); |
61 | } | 86 | } |
62 | 87 | ||
88 | static Unix_Time global_time; | ||
89 | |||
90 | /* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of | ||
91 | * unix_time() may fail to increase monotonically with increasing time */ | ||
92 | void unix_time_update(void) | ||
93 | { | ||
94 | unix_time_update_r(&global_time); | ||
95 | } | ||
96 | uint64_t unix_time(void) | ||
97 | { | ||
98 | return unix_time_get(&global_time); | ||
99 | } | ||
63 | int is_timeout(uint64_t timestamp, uint64_t timeout) | 100 | int is_timeout(uint64_t timestamp, uint64_t timeout) |
64 | { | 101 | { |
65 | return timestamp + timeout <= unix_time(); | 102 | return unix_time_is_timeout(&global_time, timestamp, timeout); |
66 | } | 103 | } |
67 | 104 | ||
68 | 105 | ||