| Index: Source/core/workers/WorkerThread.cpp
|
| diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp
|
| index d3b4156f03aa9f4e4999b71dfed1ec6575cbcd0a..ff101dd1e8a5f4749ca24b0bb1e505e6c8bed7e5 100644
|
| --- a/Source/core/workers/WorkerThread.cpp
|
| +++ b/Source/core/workers/WorkerThread.cpp
|
| @@ -38,8 +38,10 @@
|
| #include "core/workers/WorkerClients.h"
|
| #include "core/workers/WorkerReportingProxy.h"
|
| #include "core/workers/WorkerThreadStartupData.h"
|
| +#include "platform/PlatformThreadData.h"
|
| #include "platform/Task.h"
|
| #include "platform/ThreadSafeFunctional.h"
|
| +#include "platform/ThreadTimers.h"
|
| #include "platform/heap/SafePoint.h"
|
| #include "platform/heap/ThreadState.h"
|
| #include "platform/weborigin/KURL.h"
|
| @@ -109,6 +111,100 @@
|
| return workerThreads().size();
|
| }
|
|
|
| +class WorkerThreadCancelableTask final : public ExecutionContextTask {
|
| + WTF_MAKE_NONCOPYABLE(WorkerThreadCancelableTask); WTF_MAKE_FAST_ALLOCATED(WorkerThreadCancelableTask);
|
| +public:
|
| + static PassOwnPtr<WorkerThreadCancelableTask> create(PassOwnPtr<Closure> closure)
|
| + {
|
| + return adoptPtr(new WorkerThreadCancelableTask(closure));
|
| + }
|
| +
|
| + virtual ~WorkerThreadCancelableTask() { }
|
| +
|
| + virtual void performTask(ExecutionContext*) override
|
| + {
|
| + if (!m_taskCanceled)
|
| + (*m_closure)();
|
| + }
|
| +
|
| + WeakPtr<WorkerThreadCancelableTask> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
|
| + void cancelTask() { m_taskCanceled = true; }
|
| +
|
| +private:
|
| + explicit WorkerThreadCancelableTask(PassOwnPtr<Closure> closure)
|
| + : m_closure(closure)
|
| + , m_weakFactory(this)
|
| + , m_taskCanceled(false)
|
| + { }
|
| +
|
| + OwnPtr<Closure> m_closure;
|
| + WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory;
|
| + bool m_taskCanceled;
|
| +};
|
| +
|
| +class WorkerSharedTimer : public SharedTimer {
|
| +public:
|
| + explicit WorkerSharedTimer(WorkerThread* workerThread)
|
| + : m_workerThread(workerThread)
|
| + , m_running(false)
|
| + { }
|
| +
|
| + typedef void (*SharedTimerFunction)();
|
| + virtual void setFiredFunction(SharedTimerFunction func)
|
| + {
|
| + m_sharedTimerFunction = func;
|
| + }
|
| +
|
| + virtual void setFireInterval(double interval)
|
| + {
|
| + ASSERT(m_sharedTimerFunction);
|
| +
|
| + // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of
|
| + // why ceil is used in the interval calculation.
|
| + int64_t delay = static_cast<int64_t>(ceil(interval * 1000));
|
| +
|
| + if (delay < 0) {
|
| + delay = 0;
|
| + }
|
| +
|
| + m_running = true;
|
| +
|
| + if (m_lastQueuedTask.get())
|
| + m_lastQueuedTask->cancelTask();
|
| +
|
| + // Now queue the task as a cancellable one.
|
| + OwnPtr<WorkerThreadCancelableTask> task = WorkerThreadCancelableTask::create(bind(&WorkerSharedTimer::OnTimeout, this));
|
| + m_lastQueuedTask = task->createWeakPtr();
|
| + m_workerThread->postDelayedTask(FROM_HERE, task.release(), delay);
|
| + }
|
| +
|
| + virtual void stop()
|
| + {
|
| + m_running = false;
|
| + m_lastQueuedTask = nullptr;
|
| + }
|
| +
|
| +private:
|
| + void OnTimeout()
|
| + {
|
| + ASSERT(m_workerThread->workerGlobalScope());
|
| +
|
| + m_lastQueuedTask = nullptr;
|
| +
|
| + if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalScope()->isClosing())
|
| + m_sharedTimerFunction();
|
| + }
|
| +
|
| + WorkerThread* m_workerThread;
|
| + SharedTimerFunction m_sharedTimerFunction;
|
| + bool m_running;
|
| +
|
| + // The task to run OnTimeout, if any. While OnTimeout resets
|
| + // m_lastQueuedTask, this must be a weak pointer because the
|
| + // worker runloop may delete the task as it is shutting down.
|
| + WeakPtr<WorkerThreadCancelableTask> m_lastQueuedTask;
|
| +};
|
| +
|
| class WorkerThreadTask : public WebThread::Task {
|
| WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThreadTask);
|
| public:
|
| @@ -224,6 +320,8 @@
|
| m_isolate = initializeIsolate();
|
| m_workerGlobalScope = createWorkerGlobalScope(startupData);
|
| m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.get() ? cachedMetaData->size() : 0);
|
| +
|
| + PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this)));
|
| }
|
| m_webScheduler = backingThread().platformThread().scheduler();
|
|
|
| @@ -258,6 +356,7 @@
|
| m_shutdown = true;
|
| }
|
|
|
| + PlatformThreadData::current().threadTimers().setSharedTimer(nullptr);
|
| workerGlobalScope()->dispose();
|
| willDestroyIsolate();
|
|
|
| @@ -284,6 +383,9 @@
|
| workerReportingProxy().workerThreadTerminated();
|
|
|
| m_terminationEvent->signal();
|
| +
|
| + // Clean up PlatformThreadData before WTF::WTFThreadData goes away!
|
| + PlatformThreadData::current().destroy();
|
| }
|
|
|
|
|
|
|