| Index: Source/core/workers/WorkerThread.cpp
|
| diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp
|
| index 988256e367b9a256b1245ff2fdac409fb9aa786d..0775fc722f0259bce73d2697b33109e9b06b7482 100644
|
| --- a/Source/core/workers/WorkerThread.cpp
|
| +++ b/Source/core/workers/WorkerThread.cpp
|
| @@ -85,6 +85,56 @@ unsigned WorkerThread::workerThreadCount()
|
| return workerThreads().size();
|
| }
|
|
|
| +class WorkerThreadTask : public blink::WebThread::Task {
|
| + WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED;
|
| +public:
|
| + static PassOwnPtr<WorkerThreadTask> create(const WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
|
| + {
|
| + return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented));
|
| + }
|
| +
|
| + virtual ~WorkerThreadTask() { }
|
| +
|
| + virtual void run() OVERRIDE
|
| + {
|
| + WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope();
|
| + // Tasks could be put on the message loop after the cleanup task,
|
| + // ensure none of those are ran.
|
| + if (!workerGlobalScope)
|
| + return;
|
| +
|
| + if (m_isInstrumented)
|
| + InspectorInstrumentation::willPerformExecutionContextTask(workerGlobalScope, m_task.get());
|
| + if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) || m_task->isCleanupTask())
|
| + m_task->performTask(workerGlobalScope);
|
| + if (m_isInstrumented)
|
| + InspectorInstrumentation::didPerformExecutionContextTask(workerGlobalScope);
|
| + }
|
| +
|
| + base::WeakPtrFactory<blink::WebThread::Task>& weakPtrFactory()
|
| + {
|
| + return m_weakFactory;
|
| + }
|
| +
|
| +private:
|
| + WorkerThreadTask(const WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
|
| + : m_workerThread(workerThread)
|
| + , m_task(task)
|
| + , m_isInstrumented(isInstrumented)
|
| + , m_weakFactory(this)
|
| + {
|
| + if (m_isInstrumented)
|
| + m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty();
|
| + if (m_isInstrumented)
|
| + InspectorInstrumentation::didPostExecutionContextTask(m_workerThread.workerGlobalScope(), m_task.get());
|
| + }
|
| +
|
| + const WorkerThread& m_workerThread;
|
| + OwnPtr<ExecutionContextTask> m_task;
|
| + bool m_isInstrumented;
|
| + base::WeakPtrFactory<blink::WebThread::Task> m_weakFactory;
|
| +};
|
| +
|
| class WorkerSharedTimer : public SharedTimer {
|
| public:
|
| explicit WorkerSharedTimer(WorkerThread* workerThread)
|
| @@ -116,7 +166,23 @@ 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 (interval < m_lastQueuedTaskTimer->nextFireInterval()) {
|
| + m_lastQueuedTask->weakPtrFactory().InvalidateWeakPtrs();
|
| + m_lastQueuedTask = 0;
|
| + m_lastQueuedTaskTimer = 0;
|
| + }
|
| + }
|
| + if (!m_lastQueuedTask) {
|
| + // Now queue the task as a cancellable one.
|
| + WorkerThreadTask* nextDelayedTask = WorkerThreadTask::create(*m_workerThread
|
| + , createSameThreadTask(&WorkerSharedTimer::OnTimeout, this), true).leakPtr();
|
| + m_workerThread->postCancellableDelayedTask(nextDelayedTask, 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_lastQueuedTask = nextDelayedTask;
|
| + m_lastQueuedTaskTimer = PlatformThreadData::current().threadTimers().timerHeap().first();
|
| + }
|
| }
|
|
|
| virtual void stop()
|
| @@ -130,6 +196,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,50 +208,12 @@ private:
|
| SharedTimerFunction m_sharedTimerFunction;
|
| double m_nextFireTime;
|
| bool m_running;
|
| + static WorkerThreadTask* m_lastQueuedTask;
|
| + static TimerBase* m_lastQueuedTaskTimer;
|
| };
|
|
|
| -class WorkerThreadTask : public blink::WebThread::Task {
|
| - WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED;
|
| -public:
|
| - static PassOwnPtr<WorkerThreadTask> create(const WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
|
| - {
|
| - return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented));
|
| - }
|
| -
|
| - virtual ~WorkerThreadTask() { }
|
| -
|
| - virtual void run() OVERRIDE
|
| - {
|
| - WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope();
|
| - // Tasks could be put on the message loop after the cleanup task,
|
| - // ensure none of those are ran.
|
| - if (!workerGlobalScope)
|
| - return;
|
| -
|
| - if (m_isInstrumented)
|
| - InspectorInstrumentation::willPerformExecutionContextTask(workerGlobalScope, m_task.get());
|
| - if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) || m_task->isCleanupTask())
|
| - m_task->performTask(workerGlobalScope);
|
| - if (m_isInstrumented)
|
| - InspectorInstrumentation::didPerformExecutionContextTask(workerGlobalScope);
|
| - }
|
| -
|
| -private:
|
| - WorkerThreadTask(const WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
|
| - : m_workerThread(workerThread)
|
| - , m_task(task)
|
| - , m_isInstrumented(isInstrumented)
|
| - {
|
| - if (m_isInstrumented)
|
| - m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty();
|
| - if (m_isInstrumented)
|
| - InspectorInstrumentation::didPostExecutionContextTask(m_workerThread.workerGlobalScope(), m_task.get());
|
| - }
|
| -
|
| - const WorkerThread& m_workerThread;
|
| - OwnPtr<ExecutionContextTask> m_task;
|
| - bool m_isInstrumented;
|
| -};
|
| +WorkerThreadTask* WorkerSharedTimer::m_lastQueuedTask = 0;
|
| +TimerBase* WorkerSharedTimer::m_lastQueuedTaskTimer = 0;
|
|
|
| class RunDebuggerQueueTask FINAL : public ExecutionContextTask {
|
| public:
|
| @@ -452,6 +484,11 @@ void WorkerThread::postDelayedTask(PassOwnPtr<ExecutionContextTask> task, long l
|
| m_thread->postDelayedTask(WorkerThreadTask::create(*this, task, true).leakPtr(), delayMs);
|
| }
|
|
|
| +void WorkerThread::postCancellableDelayedTask(WorkerThreadTask* task, long long delayMs)
|
| +{
|
| + m_thread->postCancellableDelayedTask(task->weakPtrFactory(), delayMs);
|
| +}
|
| +
|
| void WorkerThread::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task)
|
| {
|
| m_debuggerMessageQueue.append(WorkerThreadTask::create(*this, task, false));
|
|
|