@@ -27,39 +27,39 @@ int Setnonblocking(int sockfd) {
2727 return flags;
2828}
2929
30- uint32_t TimerTaskManager::AddTimerTask (const std::string& task_name, int interval_ms, bool repeat_exec,
30+ TimerTaskID TimerTaskManager::AddTimerTask (const std::string& task_name, int interval_ms, bool repeat_exec,
3131 const std::function<void ()>& task) {
3232 TimedTask new_task = {last_task_id_++, task_name, interval_ms, repeat_exec, task};
3333 id_to_task_[new_task.task_id ] = new_task;
3434
3535 int64_t next_expired_time = NowInMs () + interval_ms;
3636 exec_queue_.insert ({next_expired_time, new_task.task_id });
3737
38- if (min_interval_ms_ > interval_ms || min_interval_ms_ == -1 ) {
39- min_interval_ms_ = interval_ms;
40- }
4138 // return the id of this task
4239 return new_task.task_id ;
4340}
41+
4442int64_t TimerTaskManager::NowInMs () {
4543 auto now = std::chrono::system_clock::now ();
4644 return std::chrono::time_point_cast<std::chrono::milliseconds>(now).time_since_epoch ().count ();
4745}
48- int TimerTaskManager::ExecTimerTask () {
46+
47+ int64_t TimerTaskManager::ExecTimerTask () {
4948 std::vector<ExecTsWithId> fired_tasks_;
5049 int64_t now_in_ms = NowInMs ();
51- // traverse in ascending order
52- for (auto pair = exec_queue_. begin (); pair != exec_queue_. end (); pair++ ) {
53- if (pair-> exec_ts <= now_in_ms) {
54- auto it = id_to_task_.find (pair-> id );
50+ // traverse in ascending order, and exec expired tasks
51+ for (const auto & task : exec_queue_) {
52+ if (task. exec_ts <= now_in_ms) {
53+ auto it = id_to_task_.find (task. id );
5554 assert (it != id_to_task_.end ());
5655 it->second .fun ();
57- fired_tasks_.push_back ({pair-> exec_ts , pair-> id });
56+ fired_tasks_.push_back ({task. exec_ts , task. id });
5857 now_in_ms = NowInMs ();
5958 } else {
6059 break ;
6160 }
6261 }
62+
6363 for (auto task : fired_tasks_) {
6464 exec_queue_.erase (task);
6565 auto it = id_to_task_.find (task.id );
@@ -69,16 +69,21 @@ int TimerTaskManager::ExecTimerTask() {
6969 exec_queue_.insert ({now_in_ms + it->second .interval_ms , task.id });
7070 } else {
7171 // this task only need to be exec once, completely remove this task
72- int interval_del = it->second .interval_ms ;
7372 id_to_task_.erase (task.id );
74- if (interval_del == min_interval_ms_) {
75- RenewMinIntervalMs ();
76- }
7773 }
7874 }
79- return min_interval_ms_;
75+
76+ if (exec_queue_.empty ()) {
77+ // to avoid wasting of cpu resources, epoll use 5000ms as timeout value when no task to exec
78+ return 5000 ;
79+ }
80+
81+ int64_t gap_between_now_and_next_task = exec_queue_.begin ()->exec_ts - NowInMs ();
82+ gap_between_now_and_next_task = gap_between_now_and_next_task < 0 ? 0 : gap_between_now_and_next_task;
83+ return gap_between_now_and_next_task;
8084}
81- bool TimerTaskManager::DelTimerTaskByTaskId (uint32_t task_id) {
85+
86+ bool TimerTaskManager::DelTimerTaskByTaskId (TimerTaskID task_id) {
8287 // remove the task
8388 auto task_to_del = id_to_task_.find (task_id);
8489 if (task_to_del == id_to_task_.end ()) {
@@ -87,11 +92,6 @@ bool TimerTaskManager::DelTimerTaskByTaskId(uint32_t task_id) {
8792 int interval_del = task_to_del->second .interval_ms ;
8893 id_to_task_.erase (task_to_del);
8994
90- // renew the min_interval_ms_
91- if (interval_del == min_interval_ms_) {
92- RenewMinIntervalMs ();
93- }
94-
9595 // remove from exec queue
9696 ExecTsWithId target_key = {-1 , 0 };
9797 for (auto pair : exec_queue_) {
@@ -106,15 +106,6 @@ bool TimerTaskManager::DelTimerTaskByTaskId(uint32_t task_id) {
106106 return true ;
107107}
108108
109- void TimerTaskManager::RenewMinIntervalMs () {
110- min_interval_ms_ = -1 ;
111- for (auto pair : id_to_task_) {
112- if (pair.second .interval_ms < min_interval_ms_ || min_interval_ms_ == -1 ) {
113- min_interval_ms_ = pair.second .interval_ms ;
114- }
115- }
116- }
117-
118109TimerTaskThread::~TimerTaskThread () {
119110 if (!timer_task_manager_.Empty ()) {
120111 LOG (INFO) << " TimerTaskThread exit !!!" ;
@@ -140,9 +131,9 @@ int TimerTaskThread::StopThread() {
140131}
141132
142133void * TimerTaskThread::ThreadMain () {
143- int timeout;
134+ int32_t timeout;
144135 while (!should_stop ()) {
145- timeout = timer_task_manager_.ExecTimerTask ();
136+ timeout = static_cast < int32_t >( timer_task_manager_.ExecTimerTask () );
146137 net_multiplexer_->NetPoll (timeout);
147138 }
148139 return nullptr ;
0 commit comments