Skip to content

Commit

Permalink
Add a thread-safe version of unix_time and friends.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
iphydf committed Jul 9, 2018
1 parent 751d094 commit fe29fbf
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 12 deletions.
59 changes: 48 additions & 11 deletions toxcore/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/* 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)
Unix_Time *unix_time_new(void)
{
if (unix_base_time_value == 0) {
unix_base_time_value = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL));
Unix_Time *unixtime = (Unix_Time *)malloc(sizeof(Unix_Time));

if (unixtime == nullptr) {
return nullptr;
}

unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value;
unixtime->time = 0;
unixtime->base_time = 0;

return unixtime;
}

uint64_t unix_time(void)
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 unix_time_value;
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)
{
unix_time_update_r(&global_time);
}
uint64_t unix_time(void)
{
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);
}


Expand Down
12 changes: 11 additions & 1 deletion toxcore/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit fe29fbf

Please sign in to comment.