mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
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.
This commit is contained in:
parent
c8697ccc20
commit
4e21c06551
|
@ -36,33 +36,70 @@
|
|||
#include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */
|
||||
#include "network.h" /* for current_time_monotonic */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
Unix_Time *unix_time_new(void)
|
||||
{
|
||||
Unix_Time *unixtime = (Unix_Time *)malloc(sizeof(Unix_Time));
|
||||
|
||||
if (unixtime == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unixtime->time = 0;
|
||||
unixtime->base_time = 0;
|
||||
|
||||
return unixtime;
|
||||
}
|
||||
|
||||
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 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)
|
||||
{
|
||||
if (unix_base_time_value == 0) {
|
||||
unix_base_time_value = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL));
|
||||
}
|
||||
|
||||
unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value;
|
||||
unix_time_update_r(&global_time);
|
||||
}
|
||||
|
||||
uint64_t unix_time(void)
|
||||
{
|
||||
return unix_time_value;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user