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)))); |