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 5db6f3f0c81d7fe41ffc37109140f79ebb639687..3c05d60a1c01e9ffed289c85e6df25a1ff1d7ee8 100644 |
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
@@ -366,7 +366,6 @@ void WorkerThread::terminateInternal(TerminationMode mode) |
{ |
DCHECK(isMainThread()); |
DCHECK(m_requestedToStart); |
- bool hasBeenInitialized = true; |
{ |
// Prevent the deadlock between GC and an attempt to terminate a thread. |
@@ -376,8 +375,6 @@ void WorkerThread::terminateInternal(TerminationMode mode) |
// termination via the global scope racing each other. |
MutexLocker lock(m_threadStateMutex); |
- hasBeenInitialized = (m_threadState != ThreadState::NotStarted); |
- |
// If terminate has already been called. |
if (m_requestedToTerminate) { |
if (m_runningDebuggerTask) { |
@@ -400,12 +397,7 @@ void WorkerThread::terminateInternal(TerminationMode mode) |
} |
m_requestedToTerminate = true; |
- if (!hasBeenInitialized) { |
- // 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 initializeOnWorkerThread(). |
- setExitCode(lock, ExitCode::GracefullyTerminated); |
- } else if (shouldScheduleToTerminateExecution(lock)) { |
+ if (shouldScheduleToTerminateExecution(lock)) { |
switch (mode) { |
case TerminationMode::Forcible: |
forciblyTerminateExecution(lock, ExitCode::SyncForciblyTerminated); |
@@ -420,10 +412,8 @@ void WorkerThread::terminateInternal(TerminationMode mode) |
} |
m_workerThreadLifecycleContext->notifyContextDestroyed(); |
- if (!hasBeenInitialized) |
- return; |
- |
m_inspectorTaskRunner->kill(); |
+ |
workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, crossThreadBind(&WorkerThread::prepareForShutdownOnWorkerThread, crossThreadUnretained(this))); |
workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, crossThreadBind(&WorkerThread::performShutdownOnWorkerThread, crossThreadUnretained(this))); |
} |
@@ -480,6 +470,8 @@ bool WorkerThread::isInShutdown() |
void WorkerThread::initializeOnWorkerThread(std::unique_ptr<WorkerThreadStartupData> startupData) |
{ |
DCHECK(isCurrentThread()); |
+ DCHECK_EQ(ThreadState::NotStarted, m_threadState); |
+ |
KURL scriptURL = startupData->m_scriptURL; |
String sourceCode = startupData->m_sourceCode; |
WorkerThreadStartMode startMode = startupData->m_startMode; |
@@ -489,21 +481,6 @@ void WorkerThread::initializeOnWorkerThread(std::unique_ptr<WorkerThreadStartupD |
{ |
MutexLocker lock(m_threadStateMutex); |
- // The worker was terminated before the thread had a chance to run. |
- if (m_requestedToTerminate) { |
- DCHECK_EQ(ExitCode::GracefullyTerminated, m_exitCode); |
- |
- // Notify the proxy that the WorkerOrWorkletGlobalScope has been |
- // disposed of. This can free this thread object, hence it must not |
- // be touched afterwards. |
- m_workerReportingProxy.didTerminateWorkerThread(); |
- |
- // Notify the main thread that it is safe to deallocate our |
- // resources. |
- m_shutdownEvent->signal(); |
- return; |
- } |
- |
if (isOwningBackingThread()) |
workerBackingThread().initialize(); |
@@ -520,6 +497,8 @@ void WorkerThread::initializeOnWorkerThread(std::unique_ptr<WorkerThreadStartupD |
m_workerReportingProxy.didCreateWorkerGlobalScope(globalScope()); |
m_workerInspectorController = WorkerInspectorController::create(this); |
+ // TODO(nhiroki): Handle a case where the script controller fails to |
+ // initialize the context. |
globalScope()->scriptController()->initializeContextIfNeeded(); |
// If Origin Trials have been registered before the V8 context was ready, |
@@ -531,14 +510,15 @@ void WorkerThread::initializeOnWorkerThread(std::unique_ptr<WorkerThreadStartupD |
setThreadState(lock, ThreadState::Running); |
} |
- if (startMode == PauseWorkerGlobalScopeOnStart) { |
+ if (startMode == PauseWorkerGlobalScopeOnStart) |
startRunningDebuggerTasksOnPauseOnWorkerThread(); |
- // WorkerThread may be ready to shut down at this point if termination |
- // is requested while the debugger task is running. Shutdown sequence |
- // will start soon. |
- if (m_threadState == ThreadState::ReadyToShutdown) |
- return; |
+ if (checkRequestedToTerminateOnWorkerThread()) { |
+ // Stop further worker tasks from running after this point. WorkerThread |
+ // was requested to terminate before initialization or during running |
+ // debugger tasks. performShutdownOnWorkerThread() will be called soon. |
+ prepareForShutdownOnWorkerThread(); |
+ return; |
} |
if (globalScope()->scriptController()->isContextInitialized()) { |
@@ -584,12 +564,7 @@ void WorkerThread::prepareForShutdownOnWorkerThread() |
void WorkerThread::performShutdownOnWorkerThread() |
{ |
DCHECK(isCurrentThread()); |
-#if DCHECK_IS_ON() |
- { |
- MutexLocker lock(m_threadStateMutex); |
- DCHECK(m_requestedToTerminate); |
- } |
-#endif |
+ DCHECK(checkRequestedToTerminateOnWorkerThread()); |
DCHECK_EQ(ThreadState::ReadyToShutdown, m_threadState); |
// The below assignment will destroy the context, which will in turn notify |
@@ -645,16 +620,14 @@ void WorkerThread::performDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThread |
ThreadDebugger::idleStarted(isolate()); |
{ |
MutexLocker lock(m_threadStateMutex); |
- if (!m_requestedToTerminate) { |
- m_runningDebuggerTask = false; |
+ m_runningDebuggerTask = false; |
+ if (!m_requestedToTerminate) |
return; |
- } |
- // terminate() was called. Shutdown sequence will start soon. |
- // Keep |m_runningDebuggerTask| to prevent forcible termination from the |
- // main thread before shutdown preparation. |
+ // termiante() was called while a debugger task is running. Shutdown |
+ // sequence will start soon. |
} |
- // Stop further worker tasks to run after this point. |
- prepareForShutdownOnWorkerThread(); |
+ // Stop further debugger tasks from running after this point. |
+ m_inspectorTaskRunner->kill(); |
} |
void WorkerThread::performDebuggerTaskDontWaitOnWorkerThread() |
@@ -701,6 +674,12 @@ bool WorkerThread::isThreadStateMutexLocked(const MutexLocker& /* unused */) |
#endif |
} |
+bool WorkerThread::checkRequestedToTerminateOnWorkerThread() |
+{ |
+ MutexLocker lock(m_threadStateMutex); |
+ return m_requestedToTerminate; |
+} |
+ |
ExitCode WorkerThread::getExitCodeForTesting() |
{ |
MutexLocker lock(m_threadStateMutex); |