--- a/src/bio.c +++ b/src/bio.c @@ -349,7 +349,11 @@ void bioKillThreads(void) { for (bio_worker_data *bwd = bio_workers; bwd != bio_worker_end; ++bwd) { if (pthread_equal(bwd->bio_thread_id, pthread_self())) continue; +#ifndef __ANDROID__ if (bwd->bio_thread_id && pthread_cancel(bwd->bio_thread_id) == 0) { +#else + if (bwd->bio_thread_id && pthread_kill(bwd->bio_thread_id, SIGUSR2) == 0) { +#endif if ((err = pthread_join(bwd->bio_thread_id, NULL)) != 0) { serverLog(LL_WARNING, "Bio worker thread #%zu can not be joined: %s", bioWorkerNum(bwd), strerror(err)); } else { --- a/src/debug.c +++ b/src/debug.c @@ -2024,7 +2024,11 @@ int memtest_test_linux_anonymous_maps(void) { static void killMainThread(void) { int err; +#ifndef __ANDROID__ if (pthread_self() != server.main_thread_id && pthread_cancel(server.main_thread_id) == 0) { +#else + if (pthread_self() != server.main_thread_id && pthread_kill(server.main_thread_id, SIGUSR2) == 0) { +#endif if ((err = pthread_join(server.main_thread_id, NULL)) != 0) { serverLog(LL_WARNING, "main thread can not be joined: %s", strerror(err)); } else { --- a/src/io_threads.c +++ b/src/io_threads.c @@ -225,8 +225,10 @@ static void *IOThreadMain(void *myid) { size_t jobs_to_process = 0; IOJobQueue *jq = &io_jobs[id]; while (1) { +#ifndef __ANDROID__ /* Cancellation point so that pthread_cancel() from main thread is honored. */ pthread_testcancel(); +#endif /* Wait for jobs */ for (int j = 0; j < 1000000; j++) { @@ -289,7 +291,11 @@ static void shutdownIOThread(int id) { if (id >= server.active_io_threads_num) { pthread_mutex_unlock(&io_threads_mutex[id]); } +#ifndef __ANDROID__ pthread_cancel(tid); +#else + pthread_kill(tid, SIGUSR2); +#endif if ((err = pthread_join(tid, NULL)) != 0) { serverLog(LL_WARNING, "IO thread(tid:%lu) can not be joined: %s", (unsigned long)tid, strerror(err)); --- a/src/server.c +++ b/src/server.c @@ -2774,12 +2774,27 @@ void resetServerStats(void) { lazyfreeResetStats(); } +#ifdef __ANDROID__ +static void threadSignalHandler(int signum) { + pthread_exit(0); +} +#endif + /* Make the thread killable at any time, so that kill threads functions * can work reliably (default cancellability type is PTHREAD_CANCEL_DEFERRED). * Needed for pthread_cancel used by the fast memory test used by the crash report. */ void makeThreadKillable(void) { +#ifndef __ANDROID__ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +#else + struct sigaction actions; + memset(&actions, 0, sizeof(actions)); + sigemptyset(&actions.sa_mask); + actions.sa_flags = 0; + actions.sa_handler = threadSignalHandler; + sigaction(SIGUSR2, &actions, NULL); +#endif } /* Return non-zero if the database is empty */