diff options
-rw-r--r-- | toxcore/mono_time.c | 29 | ||||
-rw-r--r-- | toxcore/mono_time.h | 10 | ||||
-rw-r--r-- | toxcore/mono_time_test.cc | 24 |
3 files changed, 61 insertions, 2 deletions
diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c index 5130ee6d..7fdf2d7e 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c | |||
@@ -28,8 +28,13 @@ | |||
28 | struct Mono_Time { | 28 | struct Mono_Time { |
29 | uint64_t time; | 29 | uint64_t time; |
30 | uint64_t base_time; | 30 | uint64_t base_time; |
31 | |||
32 | mono_time_current_time_cb *current_time_callback; | ||
33 | void *user_data; | ||
31 | }; | 34 | }; |
32 | 35 | ||
36 | static mono_time_current_time_cb current_time_monotonic_default; | ||
37 | |||
33 | Mono_Time *mono_time_new(void) | 38 | Mono_Time *mono_time_new(void) |
34 | { | 39 | { |
35 | Mono_Time *mono_time = (Mono_Time *)malloc(sizeof(Mono_Time)); | 40 | Mono_Time *mono_time = (Mono_Time *)malloc(sizeof(Mono_Time)); |
@@ -38,6 +43,9 @@ Mono_Time *mono_time_new(void) | |||
38 | return nullptr; | 43 | return nullptr; |
39 | } | 44 | } |
40 | 45 | ||
46 | mono_time->current_time_callback = current_time_monotonic_default; | ||
47 | mono_time->user_data = nullptr; | ||
48 | |||
41 | mono_time->time = 0; | 49 | mono_time->time = 0; |
42 | mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL); | 50 | mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL); |
43 | 51 | ||
@@ -66,6 +74,24 @@ bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64 | |||
66 | return timestamp + timeout <= mono_time_get(mono_time); | 74 | return timestamp + timeout <= mono_time_get(mono_time); |
67 | } | 75 | } |
68 | 76 | ||
77 | void mono_time_set_current_time_callback(Mono_Time *mono_time, | ||
78 | mono_time_current_time_cb *current_time_callback, void *user_data) | ||
79 | { | ||
80 | if (current_time_callback == nullptr) { | ||
81 | mono_time->current_time_callback = current_time_monotonic_default; | ||
82 | mono_time->user_data = nullptr; | ||
83 | } else { | ||
84 | mono_time->current_time_callback = current_time_callback; | ||
85 | mono_time->user_data = user_data; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* return current monotonic time in milliseconds (ms). */ | ||
90 | uint64_t current_time_monotonic(const Mono_Time *mono_time) | ||
91 | { | ||
92 | return mono_time->current_time_callback(mono_time->user_data); | ||
93 | } | ||
94 | |||
69 | //!TOKSTYLE- | 95 | //!TOKSTYLE- |
70 | // No global mutable state in Tokstyle. | 96 | // No global mutable state in Tokstyle. |
71 | #ifdef OS_WIN32 | 97 | #ifdef OS_WIN32 |
@@ -74,8 +100,7 @@ static uint64_t add_clock_mono; | |||
74 | #endif | 100 | #endif |
75 | //!TOKSTYLE+ | 101 | //!TOKSTYLE+ |
76 | 102 | ||
77 | /* return current monotonic time in milliseconds (ms). */ | 103 | static uint64_t current_time_monotonic_default(void *user_data) |
78 | uint64_t current_time_monotonic(const Mono_Time *mono_time) | ||
79 | { | 104 | { |
80 | uint64_t time; | 105 | uint64_t time; |
81 | #ifdef OS_WIN32 | 106 | #ifdef OS_WIN32 |
diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h index ed69e3b0..b735f2c3 100644 --- a/toxcore/mono_time.h +++ b/toxcore/mono_time.h | |||
@@ -52,6 +52,16 @@ bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64 | |||
52 | /* return current monotonic time in milliseconds (ms). */ | 52 | /* return current monotonic time in milliseconds (ms). */ |
53 | uint64_t current_time_monotonic(const Mono_Time *mono_time); | 53 | uint64_t current_time_monotonic(const Mono_Time *mono_time); |
54 | 54 | ||
55 | typedef uint64_t mono_time_current_time_cb(void *user_data); | ||
56 | |||
57 | /* Override implementation of current_time_monotonic() (for tests). | ||
58 | * | ||
59 | * The caller is obligated to ensure that current_time_monotonic() continues | ||
60 | * to increase monotonically. | ||
61 | */ | ||
62 | void mono_time_set_current_time_callback(Mono_Time *mono_time, | ||
63 | mono_time_current_time_cb *current_time_callback, void *user_data); | ||
64 | |||
55 | #ifdef __cplusplus | 65 | #ifdef __cplusplus |
56 | } | 66 | } |
57 | #endif | 67 | #endif |
diff --git a/toxcore/mono_time_test.cc b/toxcore/mono_time_test.cc index 4ed59406..6e81ac7e 100644 --- a/toxcore/mono_time_test.cc +++ b/toxcore/mono_time_test.cc | |||
@@ -35,4 +35,28 @@ TEST(MonoTime, IsTimeout) { | |||
35 | mono_time_free(mono_time); | 35 | mono_time_free(mono_time); |
36 | } | 36 | } |
37 | 37 | ||
38 | static uint64_t test_current_time_callback(void *user_data) { return *(uint64_t *)user_data; } | ||
39 | |||
40 | TEST(MonoTime, CustomTime) { | ||
41 | Mono_Time *mono_time = mono_time_new(); | ||
42 | |||
43 | uint64_t test_time = current_time_monotonic(mono_time) + 42137; | ||
44 | |||
45 | mono_time_set_current_time_callback(mono_time, test_current_time_callback, &test_time); | ||
46 | mono_time_update(mono_time); | ||
47 | |||
48 | EXPECT_EQ(current_time_monotonic(mono_time), test_time); | ||
49 | |||
50 | uint64_t const start = mono_time_get(mono_time); | ||
51 | |||
52 | test_time += 7000; | ||
53 | |||
54 | mono_time_update(mono_time); | ||
55 | EXPECT_EQ(mono_time_get(mono_time) - start, 7); | ||
56 | |||
57 | EXPECT_EQ(current_time_monotonic(mono_time), test_time); | ||
58 | |||
59 | mono_time_free(mono_time); | ||
60 | } | ||
61 | |||
38 | } // namespace | 62 | } // namespace |