| Index: Source/platform/TimerTest.cpp
|
| diff --git a/Source/platform/TimerTest.cpp b/Source/platform/TimerTest.cpp
|
| index 4773cd6ddc1ea71ef48c980781dbd57b29b89f3a..439e71e0e8eaeab5fe14f830daeaca172ca61ee4 100644
|
| --- a/Source/platform/TimerTest.cpp
|
| +++ b/Source/platform/TimerTest.cpp
|
| @@ -23,9 +23,58 @@ double currentTime()
|
| return gCurrentTimeSecs;
|
| }
|
|
|
| +// This class exists because gcc doesn't know how to move an OwnPtr.
|
| +class RefCountedTaskContainer : public RefCounted<RefCountedTaskContainer> {
|
| +public:
|
| + explicit RefCountedTaskContainer(WebThread::Task* task) : m_task(adoptPtr(task)) { }
|
| +
|
| + ~RefCountedTaskContainer() { }
|
| +
|
| + void run()
|
| + {
|
| + m_task->run();
|
| + }
|
| +
|
| +private:
|
| + OwnPtr<WebThread::Task> m_task;
|
| +};
|
| +
|
| +class DelayedTask {
|
| +public:
|
| + DelayedTask(WebThread::Task* task, long long delayMs)
|
| + : m_task(adoptRef(new RefCountedTaskContainer(task)))
|
| + , m_runTimeSecs(monotonicallyIncreasingTime() + 0.001 * static_cast<double>(delayMs))
|
| + , m_delayMs(delayMs) { }
|
| +
|
| + bool operator<(const DelayedTask& other) const
|
| + {
|
| + return m_runTimeSecs > other.m_runTimeSecs;
|
| + }
|
| +
|
| + void run() const
|
| + {
|
| + m_task->run();
|
| + }
|
| +
|
| + double runTimeSecs() const
|
| + {
|
| + return m_runTimeSecs;
|
| + }
|
| +
|
| + long long delayMs() const
|
| + {
|
| + return m_delayMs;
|
| + }
|
| +
|
| +private:
|
| + RefPtr<RefCountedTaskContainer> m_task;
|
| + double m_runTimeSecs;
|
| + long long m_delayMs;
|
| +};
|
| +
|
| class MockWebScheduler : public WebScheduler {
|
| public:
|
| - explicit MockWebScheduler() { }
|
| + MockWebScheduler() { }
|
| ~MockWebScheduler() override { }
|
|
|
| bool shouldYieldForHighPriorityWork() override
|
| @@ -56,12 +105,49 @@ public:
|
|
|
| void postTimerTask(const WebTraceLocation&, WebThread::Task* task, long long delayMs) override
|
| {
|
| + m_timerTasks.push(DelayedTask(task, delayMs));
|
| + }
|
| +
|
| + void runUntilIdle()
|
| + {
|
| + while (!m_timerTasks.empty()) {
|
| + gCurrentTimeSecs = m_timerTasks.top().runTimeSecs();
|
| + m_timerTasks.top().run();
|
| + m_timerTasks.pop();
|
| + }
|
| + }
|
| +
|
| + void runUntilIdleOrDeadlinePassed(double deadline)
|
| + {
|
| + while (!m_timerTasks.empty()) {
|
| + if (m_timerTasks.top().runTimeSecs() > deadline) {
|
| + gCurrentTimeSecs = deadline;
|
| + break;
|
| + }
|
| + gCurrentTimeSecs = m_timerTasks.top().runTimeSecs();
|
| + m_timerTasks.top().run();
|
| + m_timerTasks.pop();
|
| + }
|
| + }
|
| +
|
| + bool hasOneTimerTask() const
|
| + {
|
| + return m_timerTasks.size() == 1;
|
| }
|
| +
|
| + long nextTimerTaskDelayMillis() const
|
| + {
|
| + ASSERT(hasOneTimerTask());
|
| + return m_timerTasks.top().delayMs();
|
| + }
|
| +
|
| +private:
|
| + std::priority_queue<DelayedTask> m_timerTasks;
|
| };
|
|
|
| class FakeWebThread : public WebThread {
|
| public:
|
| - explicit FakeWebThread(WebScheduler* webScheduler) : m_webScheduler(webScheduler) { }
|
| + FakeWebThread() : m_webScheduler(adoptPtr(new MockWebScheduler())) { }
|
| ~FakeWebThread() override { }
|
|
|
| // WebThread implementation:
|
| @@ -89,7 +175,7 @@ public:
|
|
|
| WebScheduler* scheduler() const override
|
| {
|
| - return m_webScheduler;
|
| + return m_webScheduler.get();
|
| }
|
|
|
| virtual void enterRunLoop()
|
| @@ -103,19 +189,18 @@ public:
|
| }
|
|
|
| private:
|
| - WebScheduler* m_webScheduler;
|
| + OwnPtr<MockWebScheduler> m_webScheduler;
|
| };
|
|
|
| class TimerTestPlatform : public Platform {
|
| public:
|
| - explicit TimerTestPlatform(WebThread* webThread)
|
| - : m_webThread(webThread)
|
| - , m_timerInterval(-1) { }
|
| + TimerTestPlatform()
|
| + : m_webThread(adoptPtr(new FakeWebThread())) { }
|
| ~TimerTestPlatform() override { }
|
|
|
| WebThread* currentThread() override
|
| {
|
| - return m_webThread;
|
| + return m_webThread.get();
|
| }
|
|
|
| void cryptographicallyRandomValues(unsigned char*, size_t) override
|
| @@ -129,71 +214,40 @@ public:
|
| return enabled;
|
| }
|
|
|
| - void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) override
|
| - {
|
| - s_timerFunction = timerFunction;
|
| - }
|
| -
|
| - void setSharedTimerFireInterval(double interval) override
|
| - {
|
| - m_timerInterval = interval;
|
| - }
|
| -
|
| - virtual void stopSharedTimer() override
|
| - {
|
| - m_timerInterval = -1;
|
| - }
|
| -
|
| void runUntilIdle()
|
| {
|
| - while (hasOneTimerTask()) {
|
| - gCurrentTimeSecs += m_timerInterval;
|
| - s_timerFunction();
|
| - }
|
| + mockScheduler()->runUntilIdle();
|
| }
|
|
|
| void runUntilIdleOrDeadlinePassed(double deadline)
|
| {
|
| - while (hasOneTimerTask()) {
|
| - double newTime = gCurrentTimeSecs + m_timerInterval;
|
| - if (newTime >= deadline) {
|
| - gCurrentTimeSecs = deadline;
|
| - break;
|
| - }
|
| - gCurrentTimeSecs = newTime;
|
| - s_timerFunction();
|
| - }
|
| + mockScheduler()->runUntilIdleOrDeadlinePassed(deadline);
|
| }
|
|
|
| bool hasOneTimerTask() const
|
| {
|
| - return s_timerFunction && m_timerInterval >= 0;
|
| + return mockScheduler()->hasOneTimerTask();
|
| }
|
|
|
| long nextTimerTaskDelayMillis() const
|
| {
|
| - ASSERT(hasOneTimerTask());
|
| - return static_cast<long>(m_timerInterval * 1000);
|
| + return mockScheduler()->nextTimerTaskDelayMillis();
|
| }
|
|
|
| private:
|
| - WebThread* m_webThread;
|
| - double m_timerInterval;
|
| + MockWebScheduler* mockScheduler() const
|
| + {
|
| + return static_cast<MockWebScheduler*>(m_webThread->scheduler());
|
| + }
|
|
|
| - // This needs to be static because the callback is registered only once by
|
| - // PlatformThreadData.
|
| - static SharedTimerFunction s_timerFunction;
|
| + OwnPtr<FakeWebThread> m_webThread;
|
| };
|
|
|
| -Platform::SharedTimerFunction TimerTestPlatform::s_timerFunction;
|
| -
|
| class TimerTest : public testing::Test {
|
| public:
|
| void SetUp() override
|
| {
|
| - m_mockWebScheduler = adoptPtr(new MockWebScheduler());
|
| - m_fakeWebThread = adoptPtr(new FakeWebThread(m_mockWebScheduler.get()));
|
| - m_platform = adoptPtr(new TimerTestPlatform(m_fakeWebThread.get()));
|
| + m_platform = adoptPtr(new TimerTestPlatform());
|
| m_oldPlatform = Platform::current();
|
| Platform::initialize(m_platform.get());
|
| WTF::setMonotonicallyIncreasingTimeFunction(currentTime);
|
| @@ -243,8 +297,6 @@ protected:
|
| std::vector<double> m_runTimes;
|
|
|
| private:
|
| - OwnPtr<MockWebScheduler> m_mockWebScheduler;
|
| - OwnPtr<FakeWebThread> m_fakeWebThread;
|
| OwnPtr<TimerTestPlatform> m_platform;
|
| Platform* m_oldPlatform;
|
| };
|
| @@ -672,7 +724,7 @@ TEST_F(TimerTest, DidChangeAlignmentInterval)
|
| EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime());
|
|
|
| timer.setAlignedFireTime(m_startTime);
|
| - timer.didChangeAlignmentInterval();
|
| + timer.didChangeAlignmentInterval(monotonicallyIncreasingTime());
|
|
|
| EXPECT_FLOAT_EQ(0.0, timer.nextFireInterval());
|
| EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval());
|
|
|