| Index: Source/core/workers/WorkerThread.cpp
|
| diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp
|
| index 166679e448d1e49897a71187389409c8dec51f31..62c3715f8b4138eea04986c34e0127439eed0d8c 100644
|
| --- a/Source/core/workers/WorkerThread.cpp
|
| +++ b/Source/core/workers/WorkerThread.cpp
|
| @@ -85,12 +85,39 @@ 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)
|
| { }
|
|
|
| typedef void (*SharedTimerFunction)();
|
| @@ -116,12 +143,19 @@ public:
|
|
|
| m_running = true;
|
| m_nextFireTime = currentTime() + interval;
|
| - m_workerThread->postDelayedTask(createSameThreadTask(&WorkerSharedTimer::OnTimeout, this), delay);
|
| +
|
| + if (m_lastQueuedTask)
|
| + m_lastQueuedTask->cancelTask();
|
| +
|
| + // Now queue the task as a cancellable one.
|
| + m_lastQueuedTask = WorkerThreadCancelableTask::create(bind(&WorkerSharedTimer::OnTimeout, this)).leakPtr();
|
| + m_workerThread->postDelayedTask(adoptPtr(m_lastQueuedTask), delay);
|
| }
|
|
|
| virtual void stop()
|
| {
|
| m_running = false;
|
| + m_lastQueuedTask = 0;
|
| }
|
|
|
| double nextFireTime() { return m_nextFireTime; }
|
| @@ -130,6 +164,9 @@ private:
|
| void OnTimeout()
|
| {
|
| ASSERT(m_workerThread->workerGlobalScope());
|
| +
|
| + m_lastQueuedTask = 0;
|
| +
|
| if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalScope()->isClosing())
|
| m_sharedTimerFunction();
|
| }
|
| @@ -138,6 +175,7 @@ private:
|
| SharedTimerFunction m_sharedTimerFunction;
|
| double m_nextFireTime;
|
| bool m_running;
|
| + WorkerThreadCancelableTask* m_lastQueuedTask;
|
| };
|
|
|
| class WorkerThreadTask : public blink::WebThread::Task {
|
|
|