summaryrefslogtreecommitdiff
path: root/toxcore/util.c
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2018-07-07 22:15:08 +0000
committeriphydf <iphydf@users.noreply.github.com>2018-07-09 21:03:08 +0000
commit4e21c065517d6e125cb1d1b9a13e886b3046b0d8 (patch)
treeec075cedb1d084867acd213c10bed2974d0b3039 /toxcore/util.c
parentc8697ccc20e12b0f4a2394c10f01ce147eeca269 (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.c59
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 */
44static uint64_t unix_time_value; 45struct Unix_Time {
45static 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 50Unix_Time *unix_time_new(void)
48 * unix_time() may fail to increase monotonically with increasing time */
49void 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
58uint64_t unix_time(void) 64void unix_time_free(Unix_Time *unixtime)
65{
66 free(unixtime);
67}
68
69void 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
78uint64_t unix_time_get(const Unix_Time *unixtime)
79{
80 return unixtime->time;
81}
82
83int 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
88static 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 */
92void unix_time_update(void)
93{
94 unix_time_update_r(&global_time);
95}
96uint64_t unix_time(void)
97{
98 return unix_time_get(&global_time);
99}
63int is_timeout(uint64_t timestamp, uint64_t timeout) 100int 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