23
23
#include < vector>
24
24
#include < memory>
25
25
#include < algorithm>
26
+ #include < atomic>
26
27
27
28
#include " loop_wdog.h"
28
29
@@ -39,31 +40,39 @@ namespace {
39
40
void OnLoopBlock (const std::string &name);
40
41
void OnLoopRecover (const std::string &name);
41
42
42
- enum class State {
43
+ // ! Loop线程的状态
44
+ enum class LoopState {
43
45
kTobeCheck , // ! 未打卡
44
46
kChecked , // ! 已打卡
45
47
kTimeout // ! 打卡超时
46
48
};
47
49
50
+ // ! WDog自身的状态
51
+ enum class WDogState {
52
+ kIdle , // !< 未启动
53
+ kRunning , // !< 运行中
54
+ kStoping , // !< 停止中
55
+ };
56
+
48
57
struct LoopInfo {
49
58
using SharedPtr = std::shared_ptr<LoopInfo>;
50
59
51
60
LoopInfo (event::Loop *l, const std::string &n) :
52
61
loop (l), name(n),
53
- state (State ::kChecked )
62
+ state (LoopState ::kChecked )
54
63
{ }
55
64
56
65
event::Loop* loop;
57
66
std::string name;
58
- State state;
67
+ LoopState state;
59
68
};
60
69
61
70
using LoopInfoVec = std::vector<LoopInfo::SharedPtr>;
62
71
63
72
LoopInfoVec _loop_info_vec; // ! 线程信息表
64
73
std::mutex _mutex_lock; // ! 锁
65
74
std::thread* _sp_thread = nullptr ; // ! 线程对象
66
- bool _keep_running = false ; // ! 线程是否继续工作标记
75
+ std::atomic<WDogState> _wdog_state (WDogState:: kIdle );
67
76
68
77
LoopWDog::LoopBlockCallback _loop_die_cb = OnLoopBlock; // ! 回调函数
69
78
LoopWDog::LoopBlockCallback _loop_recover_cb = OnLoopRecover; // ! 回调函数
@@ -73,16 +82,16 @@ void SendLoopFunc() {
73
82
std::lock_guard<std::mutex> lg (_mutex_lock);
74
83
for (auto loop_info_sptr : _loop_info_vec) {
75
84
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 ;
78
87
79
88
auto start_ts = std::chrono::steady_clock::now ();
80
89
81
90
loop_info_sptr->loop ->runInLoop (
82
91
[loop_info_sptr] {
83
- if (loop_info_sptr->state == State ::kTimeout )
92
+ if (loop_info_sptr->state == LoopState ::kTimeout )
84
93
_loop_recover_cb (loop_info_sptr->name );
85
- loop_info_sptr->state = State ::kChecked ;
94
+ loop_info_sptr->state = LoopState ::kChecked ;
86
95
},
87
96
" LoopWdog"
88
97
);
@@ -99,8 +108,8 @@ void SendLoopFunc() {
99
108
void CheckLoopTag () {
100
109
std::lock_guard<std::mutex> lg (_mutex_lock);
101
110
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 ;
104
113
_loop_die_cb (loop_info_sptr->name );
105
114
RECORD_EVENT ();
106
115
}
@@ -110,13 +119,13 @@ void CheckLoopTag() {
110
119
// ! 监控线程函数
111
120
void ThreadProc () {
112
121
LogDbg (" LoopWDog started" );
113
- while (_keep_running ) {
122
+ while (_wdog_state == WDogState:: kRunning ) {
114
123
SendLoopFunc ();
115
124
116
- for (int i = 0 ; i < 10 && _keep_running ; ++i)
125
+ for (int i = 0 ; i < 10 && _wdog_state == WDogState:: kRunning ; ++i)
117
126
std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
118
127
119
- if (_keep_running )
128
+ if (_wdog_state == WDogState:: kRunning )
120
129
CheckLoopTag ();
121
130
}
122
131
LogDbg (" LoopWDog stoped" );
@@ -140,20 +149,25 @@ void LoopWDog::SetLoopBlockCallback(const LoopBlockCallback &cb) {
140
149
}
141
150
142
151
void 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 )) {
146
154
_sp_thread = new std::thread (ThreadProc);
155
+
156
+ } else {
157
+ LogWarn (" it's not idle, state:%d" , state);
147
158
}
148
159
}
149
160
150
161
void 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 )) {
154
164
_sp_thread->join ();
155
165
CHECK_DELETE_RESET_OBJ (_sp_thread);
156
166
_loop_info_vec.clear ();
167
+ _wdog_state = WDogState::kIdle ;
168
+
169
+ } else {
170
+ LogWarn (" it's not running. state:%d" , state);
157
171
}
158
172
}
159
173
0 commit comments