From cee20c6a6605d3c23699c1a9299728ff82b6218d Mon Sep 17 00:00:00 2001 From: rongli Date: Fri, 26 Apr 2019 23:38:13 +0800 Subject: [PATCH] [data-poll-manager] fix unexpected interval (#3780) --- src/core/thread/data_poll_manager.cpp | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/core/thread/data_poll_manager.cpp b/src/core/thread/data_poll_manager.cpp index a07ad122e..6958a4771 100644 --- a/src/core/thread/data_poll_manager.cpp +++ b/src/core/thread/data_poll_manager.cpp @@ -392,18 +392,42 @@ exit: void DataPollManager::ScheduleNextPoll(PollPeriodSelector aPollPeriodSelector) { + uint32_t now; + uint32_t oldPeriod = mPollPeriod; + if (aPollPeriodSelector == kRecalculatePollPeriod) { mPollPeriod = CalculatePollPeriod(); } + now = TimerMilli::GetNow(); + if (mTimer.IsRunning()) { - mTimer.StartAt(mTimerStartTime, mPollPeriod); + if (oldPeriod != mPollPeriod) + { + // If poll interval did change and re-starting the timer from + // last start time with new poll interval would fire quickly + // (i.e., fires within window `[now, now + kMinPollPeriod]`) + // add an extra minimum delay of `kMinPollPeriod`. This + // ensures that when an internal or external request triggers + // a switch to a shorter poll interval, the first data poll + // will not be sent too quickly (and possibly before the + // response is available/prepared on the parent node). + if (TimerScheduler::IsStrictlyBefore(mTimerStartTime + mPollPeriod, now + kMinPollPeriod)) + { + mTimer.StartAt(now, kMinPollPeriod); + } + else + { + mTimer.StartAt(mTimerStartTime, mPollPeriod); + } + } + // Do nothing on the running poll timer if the poll interval doesn't change } else { - mTimerStartTime = TimerMilli::GetNow(); + mTimerStartTime = now; mTimer.StartAt(mTimerStartTime, mPollPeriod); } }