Chromium Code Reviews| Index: third_party/WebKit/Source/core/workers/WorkerThread.cpp |
| diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
| index 2df2a5ffec5362845b46e7bfd7fa33cca75aacea..842ece42f5e76576cac78b82bec1f4f9ab7fa10c 100644 |
| --- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
| +++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
| @@ -71,8 +71,11 @@ public: |
| if (WorkerOrWorkletScriptController* scriptController = globalScope->scriptController()) |
| scriptController->getRejectedPromises()->processQueue(); |
| if (globalScope->isClosing()) { |
| + // |m_workerThread| will eventually be requested to terminate. |
| m_workerThread->workerReportingProxy().workerGlobalScopeClosed(); |
| - m_workerThread->terminateFromWorkerThread(); |
| + |
| + // Dispose WorkerGlobalScope to avoid processing the next task. |
|
kinuko
2016/05/24 09:07:48
Could we make this comment a bit clearer, e.g. "to
nhiroki
2016/05/24 13:36:06
Done.
|
| + m_workerThread->prepareForShutdown(); |
| } |
| } |
| } |
| @@ -128,13 +131,7 @@ std::unique_ptr<CrossThreadClosure> WorkerThread::createWorkerThreadTask(std::un |
| } |
| WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, WorkerReportingProxy& workerReportingProxy) |
| - : m_started(false) |
| - , m_terminated(false) |
| - , m_shutdown(false) |
| - , m_pausedInDebugger(false) |
| - , m_runningDebuggerTask(false) |
| - , m_shouldTerminateV8Execution(false) |
| - , m_inspectorTaskRunner(adoptPtr(new InspectorTaskRunner())) |
| + : m_inspectorTaskRunner(adoptPtr(new InspectorTaskRunner())) |
| , m_workerLoaderProxy(workerLoaderProxy) |
| , m_workerReportingProxy(workerReportingProxy) |
| , m_terminationEvent(adoptPtr(new WaitableEvent( |
| @@ -234,29 +231,16 @@ void WorkerThread::initialize(PassOwnPtr<WorkerThreadStartupData> startupData) |
| postInitialize(); |
| } |
| -void WorkerThread::shutdown() |
| +void WorkerThread::performShutdownTask() |
|
kinuko
2016/05/24 09:07:48
nit: maybe we could rename this to performShutdown
nhiroki
2016/05/24 13:36:06
I'll make a separate CL.
nhiroki
2016/05/25 01:58:33
Uploaded a CL: https://codereview.chromium.org/201
|
| { |
| DCHECK(isCurrentThread()); |
| +#if DCHECK_IS_ON |
| { |
| MutexLocker lock(m_threadStateMutex); |
| - if (m_shutdown) |
| - return; |
| - m_shutdown = true; |
| + DCHECK(m_terminated); |
| + DCHECK(m_readyToShutdown); |
| } |
| - |
| - // This should be called before we start the shutdown procedure. |
| - workerReportingProxy().willDestroyWorkerGlobalScope(); |
| - |
| - InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope()); |
| - workerGlobalScope()->dispose(); |
| - |
| - workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.get()); |
| - postTask(BLINK_FROM_HERE, createSameThreadTask(&WorkerThread::performShutdownTask, this)); |
| -} |
| - |
| -void WorkerThread::performShutdownTask() |
| -{ |
| - DCHECK(isCurrentThread()); |
| +#endif |
| // The below assignment will destroy the context, which will in turn notify |
| // messaging proxy. We cannot let any objects survive past thread exit, |
| @@ -298,20 +282,21 @@ void WorkerThread::terminate() |
| if (m_terminationEvent) |
| m_terminationEvent->signal(); |
| - // If the thread has already initiated shutdown, just return. |
| - if (m_shutdown) |
| - return; |
| - |
| // If the worker thread was never initialized, don't start another |
| // shutdown, but still wait for the thread to signal when shutdown has |
| // completed on initialize(). |
| if (!m_workerGlobalScope) |
| return; |
| - // Ensure that tasks are being handled by thread event loop. If script |
| - // execution weren't forbidden, a while(1) loop in JS could keep the thread |
| - // alive forever. |
| - m_workerGlobalScope->scriptController()->willScheduleExecutionTermination(); |
| + // If |m_readyToShutdown| is set, scriptController() is already disposed. |
| + if (!m_readyToShutdown) { |
| + DCHECK(m_workerGlobalScope->scriptController()); |
| + |
| + // Ensure that tasks are being handled by thread event loop. If script |
| + // execution weren't forbidden, a while(1) loop in JS could keep the |
| + // thread alive forever. |
| + m_workerGlobalScope->scriptController()->willScheduleExecutionTermination(); |
| + } |
| if (workerBackingThread().workerScriptCount() == 1) { |
|
kinuko
2016/05/24 09:07:49
Actually if we've passed m_readyToShutdown we won'
nhiroki
2016/05/24 13:36:06
Right. We can assume that the execution context is
|
| // This condition is not entirely correct because other scripts |
| @@ -334,7 +319,8 @@ void WorkerThread::terminate() |
| } |
| m_inspectorTaskRunner->kill(); |
| - workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::shutdown, AllowCrossThreadAccess(this))); |
| + workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::prepareForShutdown, AllowCrossThreadAccess(this))); |
| + workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::performShutdownTask, AllowCrossThreadAccess(this))); |
| } |
| void WorkerThread::terminateAndWait() |
| @@ -358,10 +344,20 @@ void WorkerThread::terminateAndWaitForAllWorkers() |
| thread->m_shutdownEvent->wait(); |
| } |
| -void WorkerThread::terminateFromWorkerThread() |
| +void WorkerThread::prepareForShutdown() |
| { |
| DCHECK(isCurrentThread()); |
| - shutdown(); |
| + { |
| + MutexLocker lock(m_threadStateMutex); |
| + if (m_readyToShutdown) |
| + return; |
| + m_readyToShutdown = true; |
| + } |
| + |
| + workerReportingProxy().willDestroyWorkerGlobalScope(); |
| + InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope()); |
| + workerGlobalScope()->dispose(); |
| + workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.get()); |
| } |
| WorkerGlobalScope* WorkerThread::workerGlobalScope() |
| @@ -403,7 +399,7 @@ void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task) |
| { |
| { |
| MutexLocker lock(m_threadStateMutex); |
| - if (m_shutdown) |
| + if (m_readyToShutdown) |
| return; |
| } |
| m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerTask, AllowCrossThreadAccess(this), passed(std::move(task)))); |