2323#include < vector>
2424#include < memory>
2525#include < algorithm>
26+ #include < atomic>
2627
2728#include " loop_wdog.h"
2829
@@ -39,31 +40,39 @@ namespace {
3940void OnLoopBlock (const std::string &name);
4041void OnLoopRecover (const std::string &name);
4142
42- enum class State {
43+ // ! Loop线程的状态
44+ enum class LoopState {
4345 kTobeCheck , // ! 未打卡
4446 kChecked , // ! 已打卡
4547 kTimeout // ! 打卡超时
4648};
4749
50+ // ! WDog自身的状态
51+ enum class WDogState {
52+ kIdle , // !< 未启动
53+ kRunning , // !< 运行中
54+ kStoping , // !< 停止中
55+ };
56+
4857struct LoopInfo {
4958 using SharedPtr = std::shared_ptr<LoopInfo>;
5059
5160 LoopInfo (event::Loop *l, const std::string &n) :
5261 loop (l), name(n),
53- state (State ::kChecked )
62+ state (LoopState ::kChecked )
5463 { }
5564
5665 event::Loop* loop;
5766 std::string name;
58- State state;
67+ LoopState state;
5968};
6069
6170using LoopInfoVec = std::vector<LoopInfo::SharedPtr>;
6271
6372LoopInfoVec _loop_info_vec; // ! 线程信息表
6473std::mutex _mutex_lock; // ! 锁
6574std::thread* _sp_thread = nullptr ; // ! 线程对象
66- bool _keep_running = false ; // ! 线程是否继续工作标记
75+ std::atomic<WDogState> _wdog_state (WDogState:: kIdle );
6776
6877LoopWDog::LoopBlockCallback _loop_die_cb = OnLoopBlock; // ! 回调函数
6978LoopWDog::LoopBlockCallback _loop_recover_cb = OnLoopRecover; // ! 回调函数
@@ -73,16 +82,16 @@ void SendLoopFunc() {
7382 std::lock_guard<std::mutex> lg (_mutex_lock);
7483 for (auto loop_info_sptr : _loop_info_vec) {
7584 if (loop_info_sptr->loop ->isRunning ()) {
76- if (loop_info_sptr->state == State ::kChecked ) {
77- loop_info_sptr->state = State ::kTobeCheck ;
85+ if (loop_info_sptr->state == LoopState ::kChecked ) {
86+ loop_info_sptr->state = LoopState ::kTobeCheck ;
7887
7988 auto start_ts = std::chrono::steady_clock::now ();
8089
8190 loop_info_sptr->loop ->runInLoop (
8291 [loop_info_sptr] {
83- if (loop_info_sptr->state == State ::kTimeout )
92+ if (loop_info_sptr->state == LoopState ::kTimeout )
8493 _loop_recover_cb (loop_info_sptr->name );
85- loop_info_sptr->state = State ::kChecked ;
94+ loop_info_sptr->state = LoopState ::kChecked ;
8695 },
8796 " LoopWdog"
8897 );
@@ -99,8 +108,8 @@ void SendLoopFunc() {
99108void CheckLoopTag () {
100109 std::lock_guard<std::mutex> lg (_mutex_lock);
101110 for (auto loop_info_sptr: _loop_info_vec) {
102- if (loop_info_sptr->state == State ::kTobeCheck ) {
103- loop_info_sptr->state = State ::kTimeout ;
111+ if (loop_info_sptr->state == LoopState ::kTobeCheck ) {
112+ loop_info_sptr->state = LoopState ::kTimeout ;
104113 _loop_die_cb (loop_info_sptr->name );
105114 RECORD_EVENT ();
106115 }
@@ -110,13 +119,13 @@ void CheckLoopTag() {
110119// ! 监控线程函数
111120void ThreadProc () {
112121 LogDbg (" LoopWDog started" );
113- while (_keep_running ) {
122+ while (_wdog_state == WDogState:: kRunning ) {
114123 SendLoopFunc ();
115124
116- for (int i = 0 ; i < 10 && _keep_running ; ++i)
125+ for (int i = 0 ; i < 10 && _wdog_state == WDogState:: kRunning ; ++i)
117126 std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
118127
119- if (_keep_running )
128+ if (_wdog_state == WDogState:: kRunning )
120129 CheckLoopTag ();
121130 }
122131 LogDbg (" LoopWDog stoped" );
@@ -140,20 +149,25 @@ void LoopWDog::SetLoopBlockCallback(const LoopBlockCallback &cb) {
140149}
141150
142151void LoopWDog::Start () {
143- std::lock_guard<std::mutex> lg (_mutex_lock);
144- if (!_keep_running) {
145- _keep_running = true ;
152+ WDogState state = WDogState::kIdle ;
153+ if (_wdog_state.compare_exchange_strong (state, WDogState::kRunning )) {
146154 _sp_thread = new std::thread (ThreadProc);
155+
156+ } else {
157+ LogWarn (" it's not idle, state:%d" , state);
147158 }
148159}
149160
150161void LoopWDog::Stop () {
151- std::lock_guard<std::mutex> lg (_mutex_lock);
152- if (_keep_running) {
153- _keep_running = false ;
162+ WDogState state = WDogState::kRunning ;
163+ if (_wdog_state.compare_exchange_strong (state, WDogState::kStoping )) {
154164 _sp_thread->join ();
155165 CHECK_DELETE_RESET_OBJ (_sp_thread);
156166 _loop_info_vec.clear ();
167+ _wdog_state = WDogState::kIdle ;
168+
169+ } else {
170+ LogWarn (" it's not running. state:%d" , state);
157171 }
158172}
159173
0 commit comments