diff --git a/src/bio.c b/src/bio.c index cbbecb6f706c..dd99442aefaf 100644 --- a/src/bio.c +++ b/src/bio.c @@ -268,10 +268,11 @@ void bioKillThreads(void) { int err, j; for (j = 0; j < BIO_NUM_OPS; j++) { + if (bio_threads[j] == pthread_self()) continue; if (bio_threads[j] && pthread_cancel(bio_threads[j]) == 0) { if ((err = pthread_join(bio_threads[j],NULL)) != 0) { serverLog(LL_WARNING, - "Bio thread for job type #%d can be joined: %s", + "Bio thread for job type #%d can not be joined: %s", j, strerror(err)); } else { serverLog(LL_WARNING, diff --git a/src/debug.c b/src/debug.c index a59c460465ec..785ad4e41eee 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1565,12 +1565,32 @@ int memtest_test_linux_anonymous_maps(void) { } #endif +static void killMainThread(void) { + int err; + if (pthread_self() != server.main_thread_id && pthread_cancel(server.main_thread_id) == 0) { + if ((err = pthread_join(server.main_thread_id,NULL)) != 0) { + serverLog(LL_WARNING, "main thread can not be joined: %s", strerror(err)); + } else { + serverLog(LL_WARNING, "main thread terminated"); + } + } +} + +/* Kill the running threads (other than current) in an unclean way. This function + * should be used only when it's critical to stop the threads for some reason. + * Currently Redis does this only on crash (for instance on SIGSEGV) in order + * to perform a fast memory check without other threads messing with memory. */ +static void killThreads(void) { + killMainThread(); + bioKillThreads(); +} + void doFastMemoryTest(void) { #if defined(HAVE_PROC_MAPS) if (server.memcheck_enabled) { /* Test memory */ serverLogRaw(LL_WARNING|LL_RAW, "\n------ FAST MEMORY TEST ------\n"); - bioKillThreads(); + killThreads(); if (memtest_test_linux_anonymous_maps()) { serverLogRaw(LL_WARNING|LL_RAW, "!!! MEMORY ERROR DETECTED! Check your memory ASAP !!!\n"); diff --git a/src/server.c b/src/server.c index b0b12d59d9e6..e8c51ee8678b 100644 --- a/src/server.c +++ b/src/server.c @@ -2879,6 +2879,7 @@ void initServer(void) { server.aof_state = server.aof_enabled ? AOF_ON : AOF_OFF; server.hz = server.config_hz; server.pid = getpid(); + server.main_thread_id = pthread_self(); server.current_client = NULL; server.fixed_time_expire = 0; server.clients = listCreate(); @@ -5174,7 +5175,6 @@ int iAmMaster(void) { (server.cluster_enabled && nodeIsMaster(server.cluster->myself))); } - int main(int argc, char **argv) { struct timeval tv; int j; diff --git a/src/server.h b/src/server.h index 4122008dcb99..d4d8de95a68a 100644 --- a/src/server.h +++ b/src/server.h @@ -1050,6 +1050,7 @@ struct clusterState; struct redisServer { /* General */ pid_t pid; /* Main process pid. */ + pthread_t main_thread_id; /* Main thread id */ char *configfile; /* Absolute config file path, or NULL */ char *executable; /* Absolute executable file path. */ char **exec_argv; /* Executable argv vector (copy). */