diff --git a/modules/alarm/alarm.cpp b/modules/alarm/alarm.cpp index b58190a41883dd1becfb93e5b3ec375a3402bb41..3db15452b2013a7829621daec1bcb5d24fbca5d3 100644 --- a/modules/alarm/alarm.cpp +++ b/modules/alarm/alarm.cpp @@ -109,7 +109,7 @@ void Alarm::cleanup() { using_independ_timezone_ = false; timezone_offset_seconds_ = 0; state_ = State::kNone; - next_utc_sec_ = 0; + target_utc_sec_ = 0; } void Alarm::refresh() { @@ -123,7 +123,7 @@ void Alarm::refresh() { uint32_t Alarm::remainSeconds() const { uint32_t curr_utc_sec = 0; if (state_ == State::kRunning && GetCurrentUtcTime(curr_utc_sec)) { - return next_utc_sec_ - curr_utc_sec; + return target_utc_sec_ - curr_utc_sec; } return 0; } @@ -177,26 +177,30 @@ bool Alarm::activeTimer() { int timezone_offset_seconds = using_independ_timezone_ ? \ timezone_offset_seconds_ : GetSystemTimezoneOffsetSeconds(); - auto curr_local_sec = curr_utc_sec + timezone_offset_seconds; - uint32_t next_local_sec = next_utc_sec_ + timezone_offset_seconds; + auto next_utc_start_sec = std::max(curr_utc_sec, target_utc_sec_); - auto next_local_start_sec = std::max(curr_local_sec, next_local_sec); - //! Q: 为什么要用curr_local_sec与next_utc_sec_中最大值来算下一轮的时间点? + //! Q: 为什么要用curr_utc_sec与target_utc_sec_中最大值来算下一轮的时间点? //! A: 因为在实践中存在steady_clock比system_clock快的现象,会导致重复触发定时任务的问题。 //! 比如:定的时间为每天10:00:00.000触发,结果定时任务在09:59:59.995就触发了。如果下 //! 一轮的时间计算是从09:59:59:995计算,它会发现下一次的触发时间点在5ms之后。于是5ms //! 之后就再次触发一次。 //! 解决办法就是:除了第一次按当前的时间算外,后面的如果出现提前触发的,按期望的算。 //! 就如上面的例子,就算是提前触发了,后面的按10:00:00.000计算。从而避免重复触发问题 + + uint32_t next_local_start_sec = next_utc_start_sec + timezone_offset_seconds; + uint32_t next_local_sec = 0; + if (!calculateNextLocalTimeSec(next_local_start_sec, next_local_sec)) return false; - auto remain_sec = next_local_sec - curr_local_sec; + uint32_t next_utc_sec = next_local_sec - timezone_offset_seconds; + + auto remain_sec = next_utc_sec - curr_utc_sec; //! 提升精度,计算中需要等待的毫秒数 auto remain_usec = (remain_sec * 1000) - (curr_utc_usec / 1000); #if 1 - LogTrace("next_local_sec:%u, remain_sec:%u, remain_usec:%u", next_local_sec, remain_sec, remain_usec); + LogTrace("next_utc_sec:%u, remain_sec:%u, remain_usec:%u", next_utc_sec, remain_sec, remain_usec); #endif //! 启动定时器 @@ -204,11 +208,15 @@ bool Alarm::activeTimer() { sp_timer_ev_->enable(); state_ = State::kRunning; - next_utc_sec_ = next_local_sec - timezone_offset_seconds; + target_utc_sec_ = next_utc_sec; return true; } void Alarm::onTimeExpired() { +#if 1 + LogTrace("time expired, target_utc_sec:%u", target_utc_sec_); +#endif + state_ = State::kInited; activeTimer(); diff --git a/modules/alarm/alarm.h b/modules/alarm/alarm.h index 02e16e892999bea2548e4e2eb4d8ade8323a12f7..591a2102dd5078d8b2c960664fb3b5c3b600630c 100644 --- a/modules/alarm/alarm.h +++ b/modules/alarm/alarm.h @@ -27,6 +27,9 @@ namespace tbox { namespace alarm { +constexpr auto kSecondsOfDay = 60 * 60 * 24; +constexpr auto kSecondsOfWeek = kSecondsOfDay * 7; + /** * 定时器基类 */ @@ -113,7 +116,7 @@ class Alarm }; State state_ = State::kNone; //!< 当前状态 - uint32_t next_utc_sec_ = 0; + uint32_t target_utc_sec_ = 0; }; } diff --git a/modules/alarm/oneshot_alarm.cpp b/modules/alarm/oneshot_alarm.cpp index bab14d83527d20845c6d600d059bf2365a919ce9..75db9664d290fe0d22c46ee9da37c44bbf9fd85c 100644 --- a/modules/alarm/oneshot_alarm.cpp +++ b/modules/alarm/oneshot_alarm.cpp @@ -27,10 +27,6 @@ namespace tbox { namespace alarm { -namespace { -constexpr auto kSecondsOfDay = 60 * 60 * 24; -} - bool OneshotAlarm::initialize(int seconds_of_day) { if (state_ == State::kRunning) { LogWarn("alarm is running state, disable first"); diff --git a/modules/alarm/weekly_alarm.cpp b/modules/alarm/weekly_alarm.cpp index 0cae63abbc1a66d2ac6f6c625db06cf64a15a51c..115a0d54746fd4f281fb6b4990aab5a96edea05f 100644 --- a/modules/alarm/weekly_alarm.cpp +++ b/modules/alarm/weekly_alarm.cpp @@ -27,11 +27,6 @@ namespace tbox { namespace alarm { -namespace { -constexpr auto kSecondsOfDay = 60 * 60 * 24; -constexpr auto kSecondsOfWeek = kSecondsOfDay * 7; -} - bool WeeklyAlarm::initialize(int seconds_of_day, const std::string &week_mask) { if (state_ == State::kRunning) { LogWarn("alarm is running state, disable first"); diff --git a/modules/alarm/workday_alarm.cpp b/modules/alarm/workday_alarm.cpp index 32270d10c9075e87a4d61ab4c2aa174c44dbd4ea..3fb5ffbf2dd3697c53c559a334568c4320d62815 100644 --- a/modules/alarm/workday_alarm.cpp +++ b/modules/alarm/workday_alarm.cpp @@ -29,10 +29,6 @@ namespace tbox { namespace alarm { -namespace { -constexpr auto kSecondsOfDay = 60 * 60 * 24; -} - bool WorkdayAlarm::initialize(int seconds_of_day, WorkdayCalendar *wp_calendar, bool workday) { if (state_ == State::kRunning) { LogWarn("alarm is running state, disable first"); diff --git a/version.mk b/version.mk index 44f04f23c909187f54ff90e5ecff9af91c1802bd..1ab21f3be6545dcdb0e84657b23ee23aecbe0944 100644 --- a/version.mk +++ b/version.mk @@ -21,4 +21,4 @@ # TBOX版本号 TBOX_VERSION_MAJOR := 1 TBOX_VERSION_MINOR := 10 -TBOX_VERSION_REVISION := 10 +TBOX_VERSION_REVISION := 11