From 016d20d33a75ee8bf08020e306f320a825c13da5 Mon Sep 17 00:00:00 2001 From: gitccl Date: Sat, 7 Jun 2025 23:39:40 +0800 Subject: [PATCH 1/3] Fix race condition that causes TimerThread to hang during shutdown --- src/bthread/timer_thread.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bthread/timer_thread.cpp b/src/bthread/timer_thread.cpp index ee80568c93..46d05a8971 100644 --- a/src/bthread/timer_thread.cpp +++ b/src/bthread/timer_thread.cpp @@ -347,6 +347,11 @@ void TimerThread::run() { // would run the consumed tasks. { BAIDU_SCOPED_LOCK(_mutex); + if (__builtin_expect(_nearest_run_time == 0, 0)) { + // If _nearest_run_time is 0, it means that stop_and_join() was called + CHECK(_stop.load(butil::memory_order_relaxed)); + break; + } _nearest_run_time = std::numeric_limits::max(); } From 15ad84ff7f6e7f67b13833c11b141a6d2a80e393 Mon Sep 17 00:00:00 2001 From: gitccl Date: Sun, 8 Jun 2025 00:41:24 +0800 Subject: [PATCH 2/3] fix ut --- src/bthread/timer_thread.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bthread/timer_thread.cpp b/src/bthread/timer_thread.cpp index 46d05a8971..026cee7e02 100644 --- a/src/bthread/timer_thread.cpp +++ b/src/bthread/timer_thread.cpp @@ -347,8 +347,8 @@ void TimerThread::run() { // would run the consumed tasks. { BAIDU_SCOPED_LOCK(_mutex); - if (__builtin_expect(_nearest_run_time == 0, 0)) { - // If _nearest_run_time is 0, it means that stop_and_join() was called + if (__builtin_expect(_nearest_run_time == -1, 0)) { + // If _nearest_run_time is -1, it means that stop_and_join() was called CHECK(_stop.load(butil::memory_order_relaxed)); break; } @@ -447,7 +447,7 @@ void TimerThread::stop_and_join() { { BAIDU_SCOPED_LOCK(_mutex); // trigger pull_again and wakeup TimerThread - _nearest_run_time = 0; + _nearest_run_time = -1; ++_nsignals; } if (pthread_self() != _thread) { From 6f20c134e509fb8cc8316d0c65a1b2c47719bcb6 Mon Sep 17 00:00:00 2001 From: gitccl Date: Fri, 13 Jun 2025 20:02:06 +0800 Subject: [PATCH 3/3] optimize timer_thread stop check --- src/bthread/timer_thread.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bthread/timer_thread.cpp b/src/bthread/timer_thread.cpp index 026cee7e02..8d61b85735 100644 --- a/src/bthread/timer_thread.cpp +++ b/src/bthread/timer_thread.cpp @@ -347,9 +347,9 @@ void TimerThread::run() { // would run the consumed tasks. { BAIDU_SCOPED_LOCK(_mutex); - if (__builtin_expect(_nearest_run_time == -1, 0)) { - // If _nearest_run_time is -1, it means that stop_and_join() was called - CHECK(_stop.load(butil::memory_order_relaxed)); + // This check of _stop ensures we won't miss the reset of _nearest_run_time + // to 0 in stop_and_join, avoiding potential race conditions. + if (BAIDU_UNLIKELY(_stop.load(butil::memory_order_relaxed))) { break; } _nearest_run_time = std::numeric_limits::max(); @@ -447,7 +447,7 @@ void TimerThread::stop_and_join() { { BAIDU_SCOPED_LOCK(_mutex); // trigger pull_again and wakeup TimerThread - _nearest_run_time = -1; + _nearest_run_time = 0; ++_nsignals; } if (pthread_self() != _thread) {