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 62c4fd888ac86f03869271c109be5607ccb159c8..49d1965e8657fd2736ad8a928465716d4cc93b8d 100644 |
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
@@ -90,6 +90,11 @@ private: |
// Shutdown sequence is now running. Just return. |
return; |
} |
+ if (m_workerThread->m_runningDebuggerTask) { |
+ // Any debugger task is guaranteed to finish, so we can wait for the |
+ // completion. Shutdown sequence will start after that. |
+ return; |
+ } |
m_workerThread->forciblyTerminateExecution(); |
DCHECK_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->m_exitCode); |
@@ -215,27 +220,34 @@ bool WorkerThread::isCurrentThread() |
void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task) |
{ |
+ { |
+ MutexLocker lock(m_threadStateMutex); |
+ if (m_terminated || m_readyToShutdown) |
+ return; |
+ } |
workerBackingThread().backingThread().postTask(location, createWorkerThreadTask(std::move(task), true)); |
} |
void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task) |
{ |
+ DCHECK(isMainThread()); |
{ |
MutexLocker lock(m_threadStateMutex); |
- if (m_readyToShutdown) |
+ if (m_terminated) |
return; |
} |
- m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task)))); |
+ m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::performDebuggerTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task)))); |
{ |
MutexLocker lock(m_threadStateMutex); |
- if (isolate()) |
+ if (isolate() && !m_readyToShutdown) |
m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate()); |
} |
- workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::runDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAccess(this))); |
+ workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::performDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAccess(this))); |
} |
-void WorkerThread::startRunningDebuggerTasksOnPause() |
+void WorkerThread::startRunningDebuggerTasksOnPauseOnWorkerThread() |
{ |
+ DCHECK(isCurrentThread()); |
m_pausedInDebugger = true; |
ThreadDebugger::idleStarted(isolate()); |
std::unique_ptr<CrossThreadClosure> task; |
@@ -251,8 +263,9 @@ void WorkerThread::startRunningDebuggerTasksOnPause() |
ThreadDebugger::idleFinished(isolate()); |
} |
-void WorkerThread::stopRunningDebuggerTasksOnPause() |
+void WorkerThread::stopRunningDebuggerTasksOnPauseOnWorkerThread() |
{ |
+ DCHECK(isCurrentThread()); |
m_pausedInDebugger = false; |
} |
@@ -452,7 +465,7 @@ void WorkerThread::initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData> |
} |
if (startMode == PauseWorkerGlobalScopeOnStart) |
- startRunningDebuggerTasksOnPause(); |
+ startRunningDebuggerTasksOnPauseOnWorkerThread(); |
if (m_workerGlobalScope->scriptController()->isContextInitialized()) { |
m_workerReportingProxy.didInitializeWorkerContext(); |
@@ -480,6 +493,7 @@ void WorkerThread::prepareForShutdownOnWorkerThread() |
m_exitCode = ExitCode::GracefullyTerminated; |
} |
+ m_inspectorTaskRunner->kill(); |
workerReportingProxy().willDestroyWorkerGlobalScope(); |
InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope()); |
workerGlobalScope()->dispose(); |
@@ -539,12 +553,13 @@ void WorkerThread::performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTas |
task->performTask(globalScope); |
} |
-void WorkerThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure> task) |
+void WorkerThread::performDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure> task) |
{ |
DCHECK(isCurrentThread()); |
InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get()); |
{ |
MutexLocker lock(m_threadStateMutex); |
+ DCHECK(!m_readyToShutdown); |
m_runningDebuggerTask = true; |
} |
ThreadDebugger::idleFinished(isolate()); |
@@ -562,7 +577,7 @@ void WorkerThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClos |
prepareForShutdownOnWorkerThread(); |
} |
-void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread() |
+void WorkerThread::performDebuggerTaskDontWaitOnWorkerThread() |
{ |
DCHECK(isCurrentThread()); |
std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::DontWaitForTask); |