Chromium Code Reviews| Index: Source/core/workers/WorkerThread.cpp |
| diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp |
| index 6b444d379c3e6da148216e69ff8901912ea97fad..14124885b2621042b442757e4bfc4da06e02266e 100644 |
| --- a/Source/core/workers/WorkerThread.cpp |
| +++ b/Source/core/workers/WorkerThread.cpp |
| @@ -85,12 +85,40 @@ unsigned WorkerThread::workerThreadCount() |
| return workerThreads().size(); |
| } |
| +class WorkerThreadCancelableTask FINAL : public ExecutionContextTask { |
| + WTF_MAKE_NONCOPYABLE(WorkerThreadCancelableTask); WTF_MAKE_FAST_ALLOCATED; |
| +public: |
| + static PassOwnPtr<WorkerThreadCancelableTask> create(const Closure& closure) |
| + { |
| + return adoptPtr(new WorkerThreadCancelableTask(closure)); |
| + } |
| + |
| + virtual void performTask(ExecutionContext*) OVERRIDE |
| + { |
| + if (!m_taskCanceled) |
| + m_closure(); |
| + } |
| + |
| + void cancelTask() { m_taskCanceled = true; } |
| + |
| +private: |
| + explicit WorkerThreadCancelableTask(const Closure& closure) |
| + : m_closure(closure) |
| + , m_taskCanceled(false) |
| + { } |
| + |
| + Closure m_closure; |
| + bool m_taskCanceled; |
| +}; |
| + |
| class WorkerSharedTimer : public SharedTimer { |
| public: |
| explicit WorkerSharedTimer(WorkerThread* workerThread) |
| : m_workerThread(workerThread) |
| , m_nextFireTime(0.0) |
| , m_running(false) |
| + , m_lastQueuedTask(0) |
| + , m_lastQueuedTaskTimer(0) |
| { } |
| typedef void (*SharedTimerFunction)(); |
| @@ -116,12 +144,36 @@ public: |
| m_running = true; |
| m_nextFireTime = currentTime() + interval; |
| - m_workerThread->postDelayedTask(createSameThreadTask(&WorkerSharedTimer::OnTimeout, this), delay); |
| + if (m_lastQueuedTask) { |
| + // If something was queued up before this, check if its later than the current timer |
| + if (m_lastQueuedTaskTimer->isActive()) { |
|
jochen (gone - plz use gerrit)
2014/09/19 13:37:09
ok, if you want to go without posting a task for t
Mayur Kankanwadi
2014/09/19 13:53:24
I am bit confused with this suggestion.
If we disc
|
| + if (interval < m_lastQueuedTaskTimer->nextFireInterval()) { |
| + m_lastQueuedTask->cancelTask(); |
| + m_lastQueuedTask = 0; |
| + m_lastQueuedTaskTimer = 0; |
| + } |
| + } else { |
| + m_lastQueuedTask->cancelTask(); |
| + m_lastQueuedTask = 0; |
| + m_lastQueuedTaskTimer = 0; |
| + } |
| + } |
| + if (!m_lastQueuedTask) { |
| + // Now queue the task as a cancellable one. |
| + m_lastQueuedTask = WorkerThreadCancelableTask::create(bind(&WorkerSharedTimer::OnTimeout, this)).leakPtr(); |
| + m_workerThread->postDelayedTask(adoptPtr(m_lastQueuedTask), delay); |
| + // The current timer should ideally be at the top of the heap as its assumed to be the smallest interval in the heap |
| + m_lastQueuedTaskTimer = PlatformThreadData::current().threadTimers().timerHeap().first(); |
| + } |
| } |
| virtual void stop() |
| { |
| m_running = false; |
| + if (m_lastQueuedTask) |
| + m_lastQueuedTask->cancelTask(); |
| + m_lastQueuedTask = 0; |
| + m_lastQueuedTaskTimer = 0; |
| } |
| double nextFireTime() { return m_nextFireTime; } |
| @@ -130,6 +182,10 @@ private: |
| void OnTimeout() |
| { |
| ASSERT(m_workerThread->workerGlobalScope()); |
| + |
| + m_lastQueuedTask = 0; |
| + m_lastQueuedTaskTimer = 0; |
| + |
| if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalScope()->isClosing()) |
| m_sharedTimerFunction(); |
| } |
| @@ -138,6 +194,8 @@ private: |
| SharedTimerFunction m_sharedTimerFunction; |
| double m_nextFireTime; |
| bool m_running; |
| + WorkerThreadCancelableTask* m_lastQueuedTask; |
| + TimerBase* m_lastQueuedTaskTimer; |
| }; |
| class WorkerThreadTask : public blink::WebThread::Task { |