| 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 8d6889c9357640bc1b0b48c1f7d5cd2ac8a998f7..ac0b1c3172931c475a2cb7fdfedabfb87b659835 100644
|
| --- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
|
| +++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
|
| @@ -72,8 +72,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.
|
| + m_workerThread->prepareForShutdown();
|
| }
|
| }
|
| }
|
| @@ -129,16 +132,9 @@ 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_webScheduler(nullptr)
|
| , m_terminationEvent(adoptPtr(new WaitableEvent(
|
| WaitableEvent::ResetPolicy::Manual,
|
| WaitableEvent::InitialState::NonSignaled)))
|
| @@ -240,19 +236,7 @@ void WorkerThread::initialize(PassOwnPtr<WorkerThreadStartupData> startupData)
|
| void WorkerThread::shutdown()
|
| {
|
| DCHECK(isCurrentThread());
|
| - {
|
| - MutexLocker lock(m_threadStateMutex);
|
| - if (m_shutdown)
|
| - return;
|
| - m_shutdown = true;
|
| - }
|
| -
|
| - // This should be called before we start the shutdown procedure.
|
| - workerReportingProxy().willDestroyWorkerGlobalScope();
|
| -
|
| - workerGlobalScope()->dispose();
|
| -
|
| - workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.get());
|
| + prepareForShutdown();
|
| postTask(BLINK_FROM_HERE, createSameThreadTask(&WorkerThread::performShutdownTask, this));
|
| }
|
|
|
| @@ -310,10 +294,19 @@ 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();
|
| + workerGlobalScope()->dispose();
|
| + workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.get());
|
| }
|
|
|
| WorkerGlobalScope* WorkerThread::workerGlobalScope()
|
| @@ -345,20 +338,21 @@ void WorkerThread::terminateInternal()
|
| 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) {
|
| // This condition is not entirely correct because other scripts
|
| @@ -412,7 +406,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))));
|
|
|