OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "platform/Timer.h" | 6 #include "platform/Timer.h" |
7 | 7 |
8 #include "public/platform/Platform.h" | 8 #include "public/platform/Platform.h" |
9 #include "public/platform/WebScheduler.h" | 9 #include "public/platform/WebScheduler.h" |
10 #include "public/platform/WebThread.h" | 10 #include "public/platform/WebThread.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 if (m_timerTasks.top().runTimeSecs() > deadline) { | 128 if (m_timerTasks.top().runTimeSecs() > deadline) { |
129 gCurrentTimeSecs = deadline; | 129 gCurrentTimeSecs = deadline; |
130 break; | 130 break; |
131 } | 131 } |
132 gCurrentTimeSecs = m_timerTasks.top().runTimeSecs(); | 132 gCurrentTimeSecs = m_timerTasks.top().runTimeSecs(); |
133 m_timerTasks.top().run(); | 133 m_timerTasks.top().run(); |
134 m_timerTasks.pop(); | 134 m_timerTasks.pop(); |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
| 138 void runPendingTasks() |
| 139 { |
| 140 while (!m_timerTasks.empty() && m_timerTasks.top().runTimeSecs() <= gCur
rentTimeSecs) { |
| 141 m_timerTasks.top().run(); |
| 142 m_timerTasks.pop(); |
| 143 } |
| 144 } |
| 145 |
138 bool hasOneTimerTask() const | 146 bool hasOneTimerTask() const |
139 { | 147 { |
140 return m_timerTasks.size() == 1; | 148 return m_timerTasks.size() == 1; |
141 } | 149 } |
142 | 150 |
143 long nextTimerTaskDelayMillis() const | 151 long nextTimerTaskDelayMillis() const |
144 { | 152 { |
145 ASSERT(hasOneTimerTask()); | 153 ASSERT(hasOneTimerTask()); |
146 return m_timerTasks.top().delayMs(); | 154 return m_timerTasks.top().delayMs(); |
147 } | 155 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 { | 225 { |
218 static const unsigned char enabled[] = {0}; | 226 static const unsigned char enabled[] = {0}; |
219 return enabled; | 227 return enabled; |
220 } | 228 } |
221 | 229 |
222 void runUntilIdle() | 230 void runUntilIdle() |
223 { | 231 { |
224 mockScheduler()->runUntilIdle(); | 232 mockScheduler()->runUntilIdle(); |
225 } | 233 } |
226 | 234 |
| 235 void runPendingTasks() |
| 236 { |
| 237 mockScheduler()->runPendingTasks(); |
| 238 } |
| 239 |
227 void runUntilIdleOrDeadlinePassed(double deadline) | 240 void runUntilIdleOrDeadlinePassed(double deadline) |
228 { | 241 { |
229 mockScheduler()->runUntilIdleOrDeadlinePassed(deadline); | 242 mockScheduler()->runUntilIdleOrDeadlinePassed(deadline); |
230 } | 243 } |
231 | 244 |
232 bool hasOneTimerTask() const | 245 bool hasOneTimerTask() const |
233 { | 246 { |
234 return mockScheduler()->hasOneTimerTask(); | 247 return mockScheduler()->hasOneTimerTask(); |
235 } | 248 } |
236 | 249 |
(...skipping 28 matching lines...) Expand all Loading... |
265 void TearDown() override | 278 void TearDown() override |
266 { | 279 { |
267 Platform::initialize(m_oldPlatform); | 280 Platform::initialize(m_oldPlatform); |
268 } | 281 } |
269 | 282 |
270 void countingTask(Timer<TimerTest>*) | 283 void countingTask(Timer<TimerTest>*) |
271 { | 284 { |
272 m_runTimes.push_back(monotonicallyIncreasingTime()); | 285 m_runTimes.push_back(monotonicallyIncreasingTime()); |
273 } | 286 } |
274 | 287 |
| 288 void recordNextFireTimeTask(Timer<TimerTest>* timer) |
| 289 { |
| 290 m_nextFireTimes.push_back(monotonicallyIncreasingTime() + timer->nextFir
eInterval()); |
| 291 } |
| 292 |
275 void advanceTimeBy(double timeSecs) | 293 void advanceTimeBy(double timeSecs) |
276 { | 294 { |
277 gCurrentTimeSecs += timeSecs; | 295 gCurrentTimeSecs += timeSecs; |
278 } | 296 } |
279 | 297 |
280 void runUntilIdle() | 298 void runUntilIdle() |
281 { | 299 { |
282 m_platform->runUntilIdle(); | 300 m_platform->runUntilIdle(); |
283 } | 301 } |
284 | 302 |
| 303 void runPendingTasks() |
| 304 { |
| 305 m_platform->runPendingTasks(); |
| 306 } |
| 307 |
285 void runUntilIdleOrDeadlinePassed(double deadline) | 308 void runUntilIdleOrDeadlinePassed(double deadline) |
286 { | 309 { |
287 m_platform->runUntilIdleOrDeadlinePassed(deadline); | 310 m_platform->runUntilIdleOrDeadlinePassed(deadline); |
288 } | 311 } |
289 | 312 |
290 bool hasOneTimerTask() const | 313 bool hasOneTimerTask() const |
291 { | 314 { |
292 return m_platform->hasOneTimerTask(); | 315 return m_platform->hasOneTimerTask(); |
293 } | 316 } |
294 | 317 |
295 long nextTimerTaskDelayMillis() const | 318 long nextTimerTaskDelayMillis() const |
296 { | 319 { |
297 return m_platform->nextTimerTaskDelayMillis(); | 320 return m_platform->nextTimerTaskDelayMillis(); |
298 } | 321 } |
299 | 322 |
300 protected: | 323 protected: |
301 double m_startTime; | 324 double m_startTime; |
302 std::vector<double> m_runTimes; | 325 std::vector<double> m_runTimes; |
| 326 std::vector<double> m_nextFireTimes; |
303 | 327 |
304 private: | 328 private: |
305 OwnPtr<TimerTestPlatform> m_platform; | 329 OwnPtr<TimerTestPlatform> m_platform; |
306 Platform* m_oldPlatform; | 330 Platform* m_oldPlatform; |
307 }; | 331 }; |
308 | 332 |
309 TEST_F(TimerTest, StartOneShot_Zero) | 333 TEST_F(TimerTest, StartOneShot_Zero) |
310 { | 334 { |
311 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 335 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
312 timer.startOneShot(0, FROM_HERE); | 336 timer.startOneShot(0, FROM_HERE); |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); | 753 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); |
730 | 754 |
731 timer.setAlignedFireTime(m_startTime); | 755 timer.setAlignedFireTime(m_startTime); |
732 timer.didChangeAlignmentInterval(monotonicallyIncreasingTime()); | 756 timer.didChangeAlignmentInterval(monotonicallyIncreasingTime()); |
733 | 757 |
734 EXPECT_FLOAT_EQ(0.0, timer.nextFireInterval()); | 758 EXPECT_FLOAT_EQ(0.0, timer.nextFireInterval()); |
735 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval()); | 759 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval()); |
736 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); | 760 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); |
737 } | 761 } |
738 | 762 |
| 763 TEST_F(TimerTest, RepeatingTimerDoesNotDrift) |
| 764 { |
| 765 Timer<TimerTest> timer(this, &TimerTest::recordNextFireTimeTask); |
| 766 timer.startRepeating(2.0, FROM_HERE); |
| 767 |
| 768 ASSERT(hasOneTimerTask()); |
| 769 recordNextFireTimeTask(&timer); // Scheduled to run at m_startTime + 2.0 |
| 770 |
| 771 advanceTimeBy(2.0); |
| 772 runPendingTasks(); // Scheduled to run at m_startTime + 4.0 |
| 773 |
| 774 advanceTimeBy(2.1); |
| 775 runPendingTasks(); // Scheduled to run at m_startTime + 6.0 |
| 776 |
| 777 advanceTimeBy(2.9); |
| 778 runPendingTasks(); // Scheduled to run at m_startTime + 8.0 |
| 779 |
| 780 advanceTimeBy(3.1); |
| 781 runPendingTasks(); // Scheduled to run at m_startTime + 12.0 (skips a beat) |
| 782 |
| 783 advanceTimeBy(4.0); |
| 784 runPendingTasks(); // Scheduled to run at m_startTime + 16.0 (skips a beat) |
| 785 |
| 786 advanceTimeBy(10.0); // Scheduled to run at m_startTime + 22.0 (skips a few
beats) |
| 787 runPendingTasks(); |
| 788 |
| 789 runUntilIdleOrDeadlinePassed(m_startTime + 5.5); |
| 790 EXPECT_THAT(m_nextFireTimes, ElementsAre( |
| 791 m_startTime + 2.0, |
| 792 m_startTime + 4.0, |
| 793 m_startTime + 6.0, |
| 794 m_startTime + 8.0, |
| 795 m_startTime + 12.0, |
| 796 m_startTime + 16.0, |
| 797 m_startTime + 26.0)); |
| 798 } |
739 | 799 |
740 } // namespace | 800 } // namespace |
741 } // namespace blink | 801 } // namespace blink |
OLD | NEW |