Chromium Code Reviews| Index: Source/core/workers/WorkerThread.cpp |
| diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp |
| index d8f75cc105c1285c6f3df3d80327ff396782a07a..55202cc58b653b6ea4b768c2e212a8088183daec 100644 |
| --- a/Source/core/workers/WorkerThread.cpp |
| +++ b/Source/core/workers/WorkerThread.cpp |
| @@ -58,20 +58,32 @@ namespace { |
| const int64_t kShortIdleHandlerDelayMs = 1000; |
| const int64_t kLongIdleHandlerDelayMs = 10*1000; |
| -class MicrotaskRunner : public WebThread::TaskObserver { |
| +} // namespace |
| + |
| +class WorkerMicrotaskRunner : public WebThread::TaskObserver { |
| public: |
| - explicit MicrotaskRunner(WorkerThread* workerThread) |
| + explicit WorkerMicrotaskRunner(WorkerThread* workerThread) |
| : m_workerThread(workerThread) |
| { |
| } |
| - virtual void willProcessTask() override { } |
| + virtual void willProcessTask() override |
| + { |
| + // No tasks should get executed after we have closed. |
| + if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope()) |
| + ASSERT_UNUSED(globalScope, !globalScope->isClosing()); |
| + } |
| + |
| virtual void didProcessTask() override |
| { |
| Microtask::performCheckpoint(); |
| if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope()) { |
| if (WorkerScriptController* scriptController = globalScope->script()) |
| scriptController->rejectedPromises()->processQueue(); |
| + if (globalScope->isClosing()) { |
| + m_workerThread->workerReportingProxy().workerGlobalScopeClosed(); |
| + m_workerThread->cleanup(); |
| + } |
| } |
| } |
| @@ -81,8 +93,6 @@ private: |
| WorkerThread* m_workerThread; |
| }; |
| -} // namespace |
| - |
| static Mutex& threadSetMutex() |
| { |
| AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex); |
| @@ -208,15 +218,11 @@ public: |
| virtual void run() override |
| { |
| WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope(); |
| - // Tasks could be put on the message loop after the cleanup task, |
| - // ensure none of those are ran. |
| - if (!workerGlobalScope) |
| - return; |
| + ASSERT(workerGlobalScope); |
| if (m_isInstrumented) |
| InspectorInstrumentation::willPerformExecutionContextTask(workerGlobalScope, m_task.get()); |
| - if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) || m_task->isCleanupTask()) |
| - m_task->performTask(workerGlobalScope); |
| + m_task->performTask(workerGlobalScope); |
| if (m_isInstrumented) |
| InspectorInstrumentation::didPerformExecutionContextTask(workerGlobalScope); |
| } |
| @@ -319,9 +325,9 @@ void WorkerThread::initialize() |
| return; |
| } |
| - m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); |
| + m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this)); |
| backingThread().addTaskObserver(m_microtaskRunner.get()); |
| - backingThread().attachGC(); |
| + backingThread().initialize(); |
| m_isolate = initializeIsolate(); |
| m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
| @@ -354,6 +360,13 @@ void WorkerThread::initialize() |
| void WorkerThread::cleanup() |
|
haraken
2015/05/09 15:54:36
Nit: We're mixing cleanup, destroy, dispose and sh
Sami
2015/05/11 10:35:32
Agreed, I'm open to suggestions. I think renaming
|
| { |
| + MutexLocker lock(m_threadCreationMutex); |
|
kinuko
2015/05/09 10:20:10
I don't think we need this? This lock's mainly use
Sami
2015/05/11 10:35:32
I added it because Kinuko pointed out that WorkerT
Sami
2015/05/11 10:37:34
Oops, somehow I read this comment being written by
kinuko
2015/05/11 13:26:40
;)
If I'm reading correctly stopInternal() is the
Sami
2015/05/11 14:02:36
I think this sequence of events could result in ra
|
| + ASSERT(isCurrentThread()); |
| + |
| + PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
| + workerGlobalScope()->dispose(); |
| + willDestroyIsolate(); |
| + |
| // This should be called before we start the shutdown procedure. |
| workerReportingProxy().willDestroyWorkerGlobalScope(); |
| @@ -366,10 +379,10 @@ void WorkerThread::cleanup() |
| m_workerGlobalScope->notifyContextDestroyed(); |
| m_workerGlobalScope = nullptr; |
| - backingThread().detachGC(); |
| + backingThread().removeTaskObserver(m_microtaskRunner.get()); |
| + backingThread().shutdown(); |
| destroyIsolate(); |
| - backingThread().removeTaskObserver(m_microtaskRunner.get()); |
| m_microtaskRunner = nullptr; |
| // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| @@ -382,50 +395,6 @@ void WorkerThread::cleanup() |
| PlatformThreadData::current().destroy(); |
| } |
| -class WorkerThreadShutdownFinishTask : public ExecutionContextTask { |
| -public: |
| - static PassOwnPtr<WorkerThreadShutdownFinishTask> create() |
| - { |
| - return adoptPtr(new WorkerThreadShutdownFinishTask()); |
| - } |
| - |
| - virtual void performTask(ExecutionContext *context) |
| - { |
| - WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
| - workerGlobalScope->dispose(); |
| - |
| - WorkerThread* workerThread = workerGlobalScope->thread(); |
| - workerThread->willDestroyIsolate(); |
| - workerThread->backingThread().postTask(FROM_HERE, new Task(WTF::bind(&WorkerThread::cleanup, workerThread))); |
| - } |
| - |
| - virtual bool isCleanupTask() const { return true; } |
| -}; |
| - |
| -class WorkerThreadShutdownStartTask : public ExecutionContextTask { |
| -public: |
| - static PassOwnPtr<WorkerThreadShutdownStartTask> create() |
| - { |
| - return adoptPtr(new WorkerThreadShutdownStartTask()); |
| - } |
| - |
| - virtual void performTask(ExecutionContext *context) |
| - { |
| - WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
| - workerGlobalScope->stopActiveDOMObjects(); |
| - PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
| - |
| - // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects, |
| - // which become dangling once Heap is destroyed. |
| - workerGlobalScope->removeAllEventListeners(); |
| - |
| - // Stick a shutdown command at the end of the queue, so that we deal |
| - // with all the cleanup tasks the databases post first. |
| - workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::create()); |
| - } |
| - |
| - virtual bool isCleanupTask() const { return true; } |
| -}; |
| void WorkerThread::stop() |
| { |
| @@ -473,7 +442,7 @@ void WorkerThread::stopInternal() |
| InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScope.get()); |
| m_debuggerMessageQueue.kill(); |
| - postTask(FROM_HERE, WorkerThreadShutdownStartTask::create()); |
| + backingThread().postTask(FROM_HERE, new Task(threadSafeBind(&WorkerThread::cleanup, AllowCrossThreadAccess(this)))); |
| } |
| void WorkerThread::didStartRunLoop() |