summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2018-07-04 16:44:57 +0200
committerantirez <antirez@gmail.com>2018-07-04 16:45:00 +0200
commit81778d91bf5a0007dc44293e983c7e36dfd7cc51 (patch)
tree55693dd8d8b13491edcd33f1e5ae006612d03a43
parent18d8205bbde7bd7bf007784c391fb7fdb1d0a7e4 (diff)
downloadredis-81778d91bf5a0007dc44293e983c7e36dfd7cc51.tar.gz
Cache timezone and daylight active flag for safer logging.
With such information will be able to use a private localtime() implementation serverLog(), which does not use any locking and is both thread and fork() safe.
-rw-r--r--src/server.c13
-rw-r--r--src/server.h2
2 files changed, 14 insertions, 1 deletions
diff --git a/src/server.c b/src/server.c
index 347ebcefd..2c9324006 100644
--- a/src/server.c
+++ b/src/server.c
@@ -977,6 +977,14 @@ void updateCachedTime(void) {
time_t unixtime = time(NULL);
atomicSet(server.unixtime,unixtime);
server.mstime = mstime();
+
+ /* To get information about daylight saving time, we need to call localtime_r
+ * and cache the result. However calling localtime_r in this context is safe
+ * since we will never fork() while here, in the main thread. The logging
+ * function will call a thread safe version of localtime that has no locks. */
+ struct tm tm;
+ localtime_r(&server.unixtime,&tm);
+ server.daylight_active = tm.tm_isdst;
}
/* This is our timer interrupt, called server.hz times per second.
@@ -1419,10 +1427,12 @@ void initServerConfig(void) {
pthread_mutex_init(&server.lruclock_mutex,NULL);
pthread_mutex_init(&server.unixtime_mutex,NULL);
+ updateCachedTime();
getRandomHexChars(server.runid,CONFIG_RUN_ID_SIZE);
server.runid[CONFIG_RUN_ID_SIZE] = '\0';
changeReplicationId();
clearReplicationId2();
+ server.timezone = timezone; /* Initialized by tzset(). */
server.configfile = NULL;
server.executable = NULL;
server.hz = CONFIG_DEFAULT_HZ;
@@ -2000,7 +2010,6 @@ void initServer(void) {
server.aof_last_write_status = C_OK;
server.aof_last_write_errno = 0;
server.repl_good_slaves_count = 0;
- updateCachedTime();
/* Create the timer callback, this is our way to process many background
* operations incrementally, like clients timeout, eviction of unaccessed
@@ -3861,9 +3870,11 @@ int main(int argc, char **argv) {
spt_init(argc, argv);
#endif
setlocale(LC_COLLATE,"");
+ tzset(); /* Populates 'timezone' global. */
zmalloc_set_oom_handler(redisOutOfMemoryHandler);
srand(time(NULL)^getpid());
gettimeofday(&tv,NULL);
+
char hashseed[16];
getRandomHexChars(hashseed,sizeof(hashseed));
dictSetHashFunctionSeed((uint8_t*)hashseed);
diff --git a/src/server.h b/src/server.h
index fc62710c6..47efd0336 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1192,6 +1192,8 @@ struct redisServer {
int list_compress_depth;
/* time cache */
time_t unixtime; /* Unix time sampled every cron cycle. */
+ time_t timezone; /* Cached timezone. As set by tzset(). */
+ int daylight_active; /* Currently in daylight saving time. */
long long mstime; /* Like 'unixtime' but with milliseconds resolution. */
/* Pubsub */
dict *pubsub_channels; /* Map channels to list of subscribed clients */