| Index: Source/platform/TimerTest.cpp
|
| diff --git a/Source/platform/TimerTest.cpp b/Source/platform/TimerTest.cpp
|
| index 912d1706c44439ecac46b1ede1d40506f63656c4..74531768c39a777515d63a32fa32353913b08ce4 100644
|
| --- a/Source/platform/TimerTest.cpp
|
| +++ b/Source/platform/TimerTest.cpp
|
| @@ -41,10 +41,10 @@ private:
|
|
|
| class DelayedTask {
|
| public:
|
| - DelayedTask(WebThread::Task* task, long long delayMs)
|
| + DelayedTask(WebThread::Task* task, double delaySecs)
|
| : m_task(adoptRef(new RefCountedTaskContainer(task)))
|
| - , m_runTimeSecs(monotonicallyIncreasingTime() + 0.001 * static_cast<double>(delayMs))
|
| - , m_delayMs(delayMs) { }
|
| + , m_runTimeSecs(monotonicallyIncreasingTime() + delaySecs)
|
| + , m_delaySecs(delaySecs) { }
|
|
|
| bool operator<(const DelayedTask& other) const
|
| {
|
| @@ -61,15 +61,15 @@ public:
|
| return m_runTimeSecs;
|
| }
|
|
|
| - long long delayMs() const
|
| + double delaySecs() const
|
| {
|
| - return m_delayMs;
|
| + return m_delaySecs;
|
| }
|
|
|
| private:
|
| RefPtr<RefCountedTaskContainer> m_task;
|
| double m_runTimeSecs;
|
| - long long m_delayMs;
|
| + double m_delaySecs;
|
| };
|
|
|
| class MockWebScheduler : public WebScheduler {
|
| @@ -103,9 +103,9 @@ public:
|
| {
|
| }
|
|
|
| - void postTimerTask(const WebTraceLocation&, WebThread::Task* task, long long delayMs) override
|
| + void postTimerTask(const WebTraceLocation&, WebThread::Task* task, double delaySecs) override
|
| {
|
| - m_timerTasks.push(DelayedTask(task, delayMs));
|
| + m_timerTasks.push(DelayedTask(task, delaySecs));
|
| }
|
|
|
| void postTimerTaskAt(const WebTraceLocation&, WebThread::Task* task, double monotonicTime) override
|
| @@ -135,15 +135,23 @@ public:
|
| }
|
| }
|
|
|
| + void runPendingTasks()
|
| + {
|
| + while (!m_timerTasks.empty() && m_timerTasks.top().runTimeSecs() <= gCurrentTimeSecs) {
|
| + m_timerTasks.top().run();
|
| + m_timerTasks.pop();
|
| + }
|
| + }
|
| +
|
| bool hasOneTimerTask() const
|
| {
|
| return m_timerTasks.size() == 1;
|
| }
|
|
|
| - long nextTimerTaskDelayMillis() const
|
| + double nextTimerTaskDelaySecs() const
|
| {
|
| ASSERT(hasOneTimerTask());
|
| - return m_timerTasks.top().delayMs();
|
| + return m_timerTasks.top().delaySecs();
|
| }
|
|
|
| private:
|
| @@ -224,6 +232,11 @@ public:
|
| mockScheduler()->runUntilIdle();
|
| }
|
|
|
| + void runPendingTasks()
|
| + {
|
| + mockScheduler()->runPendingTasks();
|
| + }
|
| +
|
| void runUntilIdleOrDeadlinePassed(double deadline)
|
| {
|
| mockScheduler()->runUntilIdleOrDeadlinePassed(deadline);
|
| @@ -234,9 +247,9 @@ public:
|
| return mockScheduler()->hasOneTimerTask();
|
| }
|
|
|
| - long nextTimerTaskDelayMillis() const
|
| + double nextTimerTaskDelaySecs() const
|
| {
|
| - return mockScheduler()->nextTimerTaskDelayMillis();
|
| + return mockScheduler()->nextTimerTaskDelaySecs();
|
| }
|
|
|
| private:
|
| @@ -272,6 +285,11 @@ public:
|
| m_runTimes.push_back(monotonicallyIncreasingTime());
|
| }
|
|
|
| + void recordNextFireTimeTask(Timer<TimerTest>* timer)
|
| + {
|
| + m_nextFireTimes.push_back(monotonicallyIncreasingTime() + timer->nextFireInterval());
|
| + }
|
| +
|
| void advanceTimeBy(double timeSecs)
|
| {
|
| gCurrentTimeSecs += timeSecs;
|
| @@ -282,6 +300,11 @@ public:
|
| m_platform->runUntilIdle();
|
| }
|
|
|
| + void runPendingTasks()
|
| + {
|
| + m_platform->runPendingTasks();
|
| + }
|
| +
|
| void runUntilIdleOrDeadlinePassed(double deadline)
|
| {
|
| m_platform->runUntilIdleOrDeadlinePassed(deadline);
|
| @@ -292,14 +315,15 @@ public:
|
| return m_platform->hasOneTimerTask();
|
| }
|
|
|
| - long nextTimerTaskDelayMillis() const
|
| + double nextTimerTaskDelaySecs() const
|
| {
|
| - return m_platform->nextTimerTaskDelayMillis();
|
| + return m_platform->nextTimerTaskDelaySecs();
|
| }
|
|
|
| protected:
|
| double m_startTime;
|
| std::vector<double> m_runTimes;
|
| + std::vector<double> m_nextFireTimes;
|
|
|
| private:
|
| OwnPtr<TimerTestPlatform> m_platform;
|
| @@ -312,7 +336,7 @@ TEST_F(TimerTest, StartOneShot_Zero)
|
| timer.startOneShot(0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(0.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime));
|
| @@ -324,7 +348,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancel)
|
| timer.startOneShot(0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(0.0, nextTimerTaskDelaySecs());
|
|
|
| timer.stop();
|
|
|
| @@ -338,7 +362,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost)
|
| timer.startOneShot(0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(0.0, nextTimerTaskDelaySecs());
|
|
|
| timer.stop();
|
|
|
| @@ -348,7 +372,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost)
|
| timer.startOneShot(0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(0.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime));
|
| @@ -360,7 +384,7 @@ TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning)
|
| timer.startOneShot(0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(0.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime));
|
| @@ -368,7 +392,7 @@ TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning)
|
| timer.startOneShot(0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(0.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime, m_startTime));
|
| @@ -380,7 +404,7 @@ TEST_F(TimerTest, StartOneShot_NonZero)
|
| timer.startOneShot(10.0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(10.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0));
|
| @@ -392,7 +416,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancel)
|
| timer.startOneShot(10, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(10.0, nextTimerTaskDelaySecs());
|
|
|
| timer.stop();
|
|
|
| @@ -406,7 +430,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost)
|
| timer.startOneShot(10, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(10.0, nextTimerTaskDelaySecs());
|
|
|
| timer.stop();
|
|
|
| @@ -417,7 +441,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost)
|
| timer.startOneShot(10, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(10.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(secondPostTime + 10.0));
|
| @@ -429,7 +453,7 @@ TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning)
|
| timer.startOneShot(10, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(10.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0));
|
| @@ -437,7 +461,7 @@ TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning)
|
| timer.startOneShot(20, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(20000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(20.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0, m_startTime + 30.0));
|
| @@ -450,7 +474,7 @@ TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing)
|
| timer.startOneShot(10, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(10.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdle();
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0));
|
| @@ -482,7 +506,7 @@ TEST_F(TimerTest, StartRepeatingTask)
|
| timer.startRepeating(1.0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(1000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(1.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdleOrDeadlinePassed(m_startTime + 5.5);
|
| EXPECT_THAT(m_runTimes, ElementsAre(
|
| @@ -495,7 +519,7 @@ TEST_F(TimerTest, StartRepeatingTask_ThenCancel)
|
| timer.startRepeating(1.0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(1000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(1.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdleOrDeadlinePassed(m_startTime + 2.5);
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0));
|
| @@ -512,7 +536,7 @@ TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot)
|
| timer.startRepeating(1.0, FROM_HERE);
|
|
|
| ASSERT(hasOneTimerTask());
|
| - EXPECT_EQ(1000ll, nextTimerTaskDelayMillis());
|
| + EXPECT_EQ(1.0, nextTimerTaskDelaySecs());
|
|
|
| runUntilIdleOrDeadlinePassed(m_startTime + 2.5);
|
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0));
|
| @@ -736,6 +760,42 @@ TEST_F(TimerTest, DidChangeAlignmentInterval)
|
| EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime());
|
| }
|
|
|
| +TEST_F(TimerTest, RepeatingTimerDoesNotDrift)
|
| +{
|
| + Timer<TimerTest> timer(this, &TimerTest::recordNextFireTimeTask);
|
| + timer.startRepeating(2.0, FROM_HERE);
|
| +
|
| + ASSERT(hasOneTimerTask());
|
| + recordNextFireTimeTask(&timer); // Scheduled to run at m_startTime + 2.0
|
| +
|
| + advanceTimeBy(2.0);
|
| + runPendingTasks(); // Scheduled to run at m_startTime + 4.0
|
| +
|
| + advanceTimeBy(2.1);
|
| + runPendingTasks(); // Scheduled to run at m_startTime + 6.0
|
| +
|
| + advanceTimeBy(2.9);
|
| + runPendingTasks(); // Scheduled to run at m_startTime + 8.0
|
| +
|
| + advanceTimeBy(3.1);
|
| + runPendingTasks(); // Scheduled to run at m_startTime + 12.0 (skips a beat)
|
| +
|
| + advanceTimeBy(4.0);
|
| + runPendingTasks(); // Scheduled to run at m_startTime + 16.0 (skips a beat)
|
| +
|
| + advanceTimeBy(10.0); // Scheduled to run at m_startTime + 22.0 (skips a few beats)
|
| + runPendingTasks();
|
| +
|
| + runUntilIdleOrDeadlinePassed(m_startTime + 5.5);
|
| + EXPECT_THAT(m_nextFireTimes, ElementsAre(
|
| + m_startTime + 2.0,
|
| + m_startTime + 4.0,
|
| + m_startTime + 6.0,
|
| + m_startTime + 8.0,
|
| + m_startTime + 12.0,
|
| + m_startTime + 16.0,
|
| + m_startTime + 26.0));
|
| +}
|
|
|
| } // namespace
|
| } // namespace blink
|
|
|