1 /* SPDX-License-Identifier: GPL-3.0-or-later 2 * Copyright © 2016-2020 The TokTok team. 3 * Copyright © 2014 Tox project. 4 */ 5 #ifndef C_TOXCORE_TOXCORE_MONO_TIME_H 6 #define C_TOXCORE_TOXCORE_MONO_TIME_H 7 8 #include <stdbool.h> 9 #include <stdint.h> 10 11 #ifdef __cplusplus 12 extern "C" { 13 #endif 14 15 #ifndef MONO_TIME_DEFINED 16 #define MONO_TIME_DEFINED 17 /** 18 * The timer portion of the toxcore event loop. 19 * 20 * We update the time exactly once per tox_iterate call. Programs built on lower 21 * level APIs such as the DHT bootstrap node must update the time manually in 22 * each iteration. 23 * 24 * Time is kept per Tox instance, not globally, even though "time" as a concept 25 * is global. This is because by definition `mono_time` represents the time at 26 * the start of an iteration, and also by definition the time when all network 27 * events for the current iteration occurred. This affects mainly two situations: 28 * 29 * 1. Two timers started in the same iteration: e.g. two timers set to expire in 30 * 10 seconds will both expire at the same time, i.e. about 10 seconds later. 31 * If the time were global, `mono_time` would be a random number that is 32 * either the time at the start of an iteration, or 1 second later (since the 33 * timer resolution is 1 second). This can happen when one update happens at 34 * e.g. 10:00:00.995 and a few milliseconds later a concurrently running 35 * instance updates the time at 10:00:01.005, making one timer expire a 36 * second after the other. 37 * 2. One timer based on an event: if we want to encode a behaviour of a timer 38 * expiring e.g. 10 seconds after a network event occurred, we simply start a 39 * timer in the event handler. If a concurrent instance updates the time 40 * underneath us, it may instead expire 9 seconds after the event. 41 * 42 * Both these situations cause incorrect behaviour randomly. In practice, 43 * toxcore is somewhat robust against strange timer behaviour, but the 44 * implementation should at least theoretically match the specification. 45 */ 46 typedef struct Mono_Time Mono_Time; 47 #endif /* MONO_TIME_DEFINED */ 48 49 Mono_Time *mono_time_new(void); 50 void mono_time_free(Mono_Time *mono_time); 51 52 /** 53 * Update mono_time; subsequent calls to mono_time_get or mono_time_is_timeout 54 * will use the time at the call to mono_time_update. 55 */ 56 void mono_time_update(Mono_Time *mono_time); 57 58 /** 59 * Return unix time since epoch in seconds. 60 */ 61 uint64_t mono_time_get(const Mono_Time *mono_time); 62 63 /** 64 * Return true iff timestamp is at least timeout seconds in the past. 65 */ 66 bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout); 67 68 /** 69 * Return current monotonic time in milliseconds (ms). The starting point is 70 * unspecified. 71 */ 72 uint64_t current_time_monotonic(Mono_Time *mono_time); 73 74 typedef uint64_t mono_time_current_time_cb(Mono_Time *mono_time, void *user_data); 75 76 /* Override implementation of current_time_monotonic() (for tests). 77 * 78 * The caller is obligated to ensure that current_time_monotonic() continues 79 * to increase monotonically. 80 */ 81 void mono_time_set_current_time_callback(Mono_Time *mono_time, 82 mono_time_current_time_cb *current_time_callback, void *user_data); 83 84 #ifdef __cplusplus 85 } 86 #endif 87 88 #endif // C_TOXCORE_TOXCORE_MONO_TIME_H 89