Skip to content

Commit 00ca56b

Browse files
committed
fix(alarm):1.10.11, 修复Alarm在负时区时,出现Alarm不触发问题
1 parent afa4930 commit 00ca56b

File tree

6 files changed

+22
-24
lines changed

6 files changed

+22
-24
lines changed

modules/alarm/alarm.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void Alarm::cleanup() {
109109
using_independ_timezone_ = false;
110110
timezone_offset_seconds_ = 0;
111111
state_ = State::kNone;
112-
next_utc_sec_ = 0;
112+
target_utc_sec_ = 0;
113113
}
114114

115115
void Alarm::refresh() {
@@ -123,7 +123,7 @@ void Alarm::refresh() {
123123
uint32_t Alarm::remainSeconds() const {
124124
uint32_t curr_utc_sec = 0;
125125
if (state_ == State::kRunning && GetCurrentUtcTime(curr_utc_sec)) {
126-
return next_utc_sec_ - curr_utc_sec;
126+
return target_utc_sec_ - curr_utc_sec;
127127
}
128128
return 0;
129129
}
@@ -177,38 +177,46 @@ bool Alarm::activeTimer() {
177177
int timezone_offset_seconds = using_independ_timezone_ ? \
178178
timezone_offset_seconds_ : GetSystemTimezoneOffsetSeconds();
179179

180-
auto curr_local_sec = curr_utc_sec + timezone_offset_seconds;
181-
uint32_t next_local_sec = next_utc_sec_ + timezone_offset_seconds;
180+
auto next_utc_start_sec = std::max(curr_utc_sec, target_utc_sec_);
182181

183-
auto next_local_start_sec = std::max(curr_local_sec, next_local_sec);
184-
//! Q: 为什么要用curr_local_sec与next_utc_sec_中最大值来算下一轮的时间点?
182+
//! Q: 为什么要用curr_utc_sec与target_utc_sec_中最大值来算下一轮的时间点?
185183
//! A: 因为在实践中存在steady_clock比system_clock快的现象,会导致重复触发定时任务的问题。
186184
//! 比如:定的时间为每天10:00:00.000触发,结果定时任务在09:59:59.995就触发了。如果下
187185
//! 一轮的时间计算是从09:59:59:995计算,它会发现下一次的触发时间点在5ms之后。于是5ms
188186
//! 之后就再次触发一次。
189187
//! 解决办法就是:除了第一次按当前的时间算外,后面的如果出现提前触发的,按期望的算。
190188
//! 就如上面的例子,就算是提前触发了,后面的按10:00:00.000计算。从而避免重复触发问题
189+
190+
uint32_t next_local_start_sec = next_utc_start_sec + timezone_offset_seconds;
191+
uint32_t next_local_sec = 0;
192+
191193
if (!calculateNextLocalTimeSec(next_local_start_sec, next_local_sec))
192194
return false;
193195

194-
auto remain_sec = next_local_sec - curr_local_sec;
196+
uint32_t next_utc_sec = next_local_sec - timezone_offset_seconds;
197+
198+
auto remain_sec = next_utc_sec - curr_utc_sec;
195199
//! 提升精度,计算中需要等待的毫秒数
196200
auto remain_usec = (remain_sec * 1000) - (curr_utc_usec / 1000);
197201

198202
#if 1
199-
LogTrace("next_local_sec:%u, remain_sec:%u, remain_usec:%u", next_local_sec, remain_sec, remain_usec);
203+
LogTrace("next_utc_sec:%u, remain_sec:%u, remain_usec:%u", next_utc_sec, remain_sec, remain_usec);
200204
#endif
201205

202206
//! 启动定时器
203207
sp_timer_ev_->initialize(std::chrono::milliseconds(remain_usec), event::Event::Mode::kOneshot);
204208
sp_timer_ev_->enable();
205209

206210
state_ = State::kRunning;
207-
next_utc_sec_ = next_local_sec - timezone_offset_seconds;
211+
target_utc_sec_ = next_utc_sec;
208212
return true;
209213
}
210214

211215
void Alarm::onTimeExpired() {
216+
#if 1
217+
LogTrace("time expired, target_utc_sec:%u", target_utc_sec_);
218+
#endif
219+
212220
state_ = State::kInited;
213221
activeTimer();
214222

modules/alarm/alarm.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
namespace tbox {
2828
namespace alarm {
2929

30+
constexpr auto kSecondsOfDay = 60 * 60 * 24;
31+
constexpr auto kSecondsOfWeek = kSecondsOfDay * 7;
32+
3033
/**
3134
* 定时器基类
3235
*/
@@ -113,7 +116,7 @@ class Alarm
113116
};
114117
State state_ = State::kNone; //!< 当前状态
115118

116-
uint32_t next_utc_sec_ = 0;
119+
uint32_t target_utc_sec_ = 0;
117120
};
118121

119122
}

modules/alarm/oneshot_alarm.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@
2727
namespace tbox {
2828
namespace alarm {
2929

30-
namespace {
31-
constexpr auto kSecondsOfDay = 60 * 60 * 24;
32-
}
33-
3430
bool OneshotAlarm::initialize(int seconds_of_day) {
3531
if (state_ == State::kRunning) {
3632
LogWarn("alarm is running state, disable first");

modules/alarm/weekly_alarm.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@
2727
namespace tbox {
2828
namespace alarm {
2929

30-
namespace {
31-
constexpr auto kSecondsOfDay = 60 * 60 * 24;
32-
constexpr auto kSecondsOfWeek = kSecondsOfDay * 7;
33-
}
34-
3530
bool WeeklyAlarm::initialize(int seconds_of_day, const std::string &week_mask) {
3631
if (state_ == State::kRunning) {
3732
LogWarn("alarm is running state, disable first");

modules/alarm/workday_alarm.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@
2929
namespace tbox {
3030
namespace alarm {
3131

32-
namespace {
33-
constexpr auto kSecondsOfDay = 60 * 60 * 24;
34-
}
35-
3632
bool WorkdayAlarm::initialize(int seconds_of_day, WorkdayCalendar *wp_calendar, bool workday) {
3733
if (state_ == State::kRunning) {
3834
LogWarn("alarm is running state, disable first");

version.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
# TBOX版本号
2222
TBOX_VERSION_MAJOR := 1
2323
TBOX_VERSION_MINOR := 10
24-
TBOX_VERSION_REVISION := 10
24+
TBOX_VERSION_REVISION := 11

0 commit comments

Comments
 (0)