From 00ca56b09cd629791b82285b7fb648c606f8dc4a Mon Sep 17 00:00:00 2001 From: Hevake Lee Date: Thu, 15 Aug 2024 20:16:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(alarm):1.10.11,=20=E4=BF=AE=E5=A4=8DAlarm?= =?UTF-8?q?=E5=9C=A8=E8=B4=9F=E6=97=B6=E5=8C=BA=E6=97=B6=EF=BC=8C=E5=87=BA?= =?UTF-8?q?=E7=8E=B0Alarm=E4=B8=8D=E8=A7=A6=E5=8F=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/alarm/alarm.cpp | 26 +++++++++++++++++--------- modules/alarm/alarm.h | 5 ++++- modules/alarm/oneshot_alarm.cpp | 4 ---- modules/alarm/weekly_alarm.cpp | 5 ----- modules/alarm/workday_alarm.cpp | 4 ---- version.mk | 2 +- 6 files changed, 22 insertions(+), 24 deletions(-) diff --git a/modules/alarm/alarm.cpp b/modules/alarm/alarm.cpp index b58190a..3db1545 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 02e16e8..591a210 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 bab14d8..75db966 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 0cae63a..115a0d5 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 32270d1..3fb5ffb 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 44f04f2..1ab21f3 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 -- Gitee