diff --git a/src/server.c b/src/server.c index 6aeb5aa9a..280470f63 100644 --- a/src/server.c +++ b/src/server.c @@ -2196,6 +2196,14 @@ void initServer(void) { scriptingInit(1); slowlogInit(); latencyMonitorInit(); +} + +/* Some steps in server initialization need to be done last (after modules + * are loaded). + * Specifically, creation of threads due to a race bug in ld.so, in which + * Thread Local Storage initialization collides with dlopen call. + * see: https://sourceware.org/bugzilla/show_bug.cgi?id=19329 */ +void InitServerLast() { bioInit(); server.initial_memory_usage = zmalloc_used_memory(); } @@ -4197,6 +4205,7 @@ int main(int argc, char **argv) { linuxMemoryWarnings(); #endif moduleLoadFromQueue(); + InitServerLast(); loadDataFromDisk(); if (server.cluster_enabled) { if (verifyClusterConfigWithData() == C_ERR) { @@ -4211,6 +4220,7 @@ int main(int argc, char **argv) { if (server.sofd > 0) serverLog(LL_NOTICE,"The server is now ready to accept connections at %s", server.unixsocket); } else { + InitServerLast(); sentinelIsRunning(); } diff --git a/src/zmalloc.c b/src/zmalloc.c index 2482f512b..dd655620c 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -323,6 +323,13 @@ int zmalloc_get_allocator_info(size_t *allocated, je_mallctl("stats.allocated", allocated, &sz, NULL, 0); return 1; } + +void set_jemalloc_bg_thread(int enable) { + /* let jemalloc do purging asynchronously, required when there's no traffic + * after flushdb */ + char val = !!enable; + je_mallctl("background_thread", NULL, 0, &val, 1); +} #else int zmalloc_get_allocator_info(size_t *allocated, size_t *active,