Chromium Code Reviews| Index: third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThread.cpp |
| diff --git a/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThread.cpp b/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThread.cpp |
| index fa420027933081e3485cf6dce85ce7dc3144510f..400713bfd77d70cc62a0f648cd958f0ed0cc9cbf 100644 |
| --- a/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThread.cpp |
| +++ b/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThread.cpp |
| @@ -5,17 +5,139 @@ |
| #include "config.h" |
| #include "modules/compositorworker/CompositorWorkerThread.h" |
| +#include "bindings/core/v8/V8GCController.h" |
| #include "bindings/core/v8/V8Initializer.h" |
| #include "core/workers/WorkerObjectProxy.h" |
| #include "core/workers/WorkerThreadStartupData.h" |
| #include "modules/compositorworker/CompositorWorkerGlobalScope.h" |
| -#include "modules/compositorworker/CompositorWorkerManager.h" |
| +#include "platform/ThreadSafeFunctional.h" |
| +#include "platform/TraceEvent.h" |
| #include "public/platform/Platform.h" |
| namespace blink { |
| +namespace { |
| + |
| +void destroyThread(WebThreadSupportingGC* thread) |
| +{ |
|
haraken
2015/12/03 05:19:31
It would be helpful to add ASSERT(isMainThread())
yhirano
2016/02/02 06:38:20
Hi haraken@, I wanna understand the comment. Is th
haraken
2016/02/02 07:07:56
Good point. A blocking operation happens in the We
|
| + delete thread; |
| +} |
| + |
| +class CompositorWorkerSharedState { |
| +public: |
| + static CompositorWorkerSharedState& instance() |
| + { |
| + AtomicallyInitializedStaticReference(CompositorWorkerSharedState, compositorWorkerSharedState, (new CompositorWorkerSharedState())); |
| + return compositorWorkerSharedState; |
| + } |
| + |
| + WebThreadSupportingGC* compositorWorkerThread() |
| + { |
| + MutexLocker lock(m_mutex); |
| + if (!m_thread && isMainThread()) { |
| + ASSERT(!m_workerCount); |
| + WebThread* platformThread = Platform::current()->compositorThread(); |
| + m_thread = WebThreadSupportingGC::createForThread(platformThread); |
| + } |
| + return m_thread.get(); |
| + } |
| + |
| + void initializeBackingThread() |
| + { |
| + MutexLocker lock(m_mutex); |
| + ASSERT(m_thread->isCurrentThread()); |
| + ++m_workerCount; |
| + if (m_workerCount > 1) |
| + return; |
| + |
| + m_thread->initialize(); |
| + |
| + // Initialize the isolate at the same time. |
| + ASSERT(!m_isolate); |
| + m_isolate = V8PerIsolateData::initialize(); |
| + V8Initializer::initializeWorker(m_isolate); |
| + |
| + OwnPtr<V8IsolateInterruptor> interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate)); |
| + ThreadState::current()->addInterruptor(interruptor.release()); |
| + ThreadState::current()->registerTraceDOMWrappers(m_isolate, V8GCController::traceDOMWrappers); |
| + } |
| + |
| + void shutdownBackingThread() |
| + { |
| + MutexLocker lock(m_mutex); |
| + ASSERT(m_thread->isCurrentThread()); |
| + ASSERT(m_workerCount > 0); |
| + --m_workerCount; |
| + if (m_workerCount == 0) { |
| + m_thread->shutdown(); |
| + Platform::current()->mainThread()->taskRunner()->postTask( |
| + BLINK_FROM_HERE, threadSafeBind(destroyThread, AllowCrossThreadAccess(m_thread.leakPtr()))); |
| + } |
| + } |
| + |
| + v8::Isolate* initializeIsolate() |
| + { |
| + MutexLocker lock(m_mutex); |
| + ASSERT(m_thread->isCurrentThread()); |
| + ASSERT(m_isolate); |
| + // It is safe to use the existing isolate even if TerminateExecution() has been |
| + // called on it, without calling CancelTerminateExecution(). |
| + return m_isolate; |
| + } |
| + |
| + void willDestroyIsolate() |
| + { |
| + MutexLocker lock(m_mutex); |
| + ASSERT(m_thread->isCurrentThread()); |
| + if (m_workerCount == 1) |
| + V8PerIsolateData::willBeDestroyed(m_isolate); |
| + } |
| + |
| + void destroyIsolate() |
| + { |
| + MutexLocker lock(m_mutex); |
| + if (!m_thread) { |
| + ASSERT(m_workerCount == 0); |
| + V8PerIsolateData::destroy(m_isolate); |
| + m_isolate = nullptr; |
| + } |
| + } |
| + |
| + void terminateV8Execution() |
| + { |
| + MutexLocker lock(m_mutex); |
| + ASSERT(isMainThread()); |
| + if (m_workerCount > 1) |
| + return; |
| + |
| + v8::V8::TerminateExecution(m_isolate); |
| + } |
| + |
| + bool hasThreadForTest() |
| + { |
| + return m_thread; |
| + } |
| + |
| + bool hasIsolateForTest() |
| + { |
| + return m_isolate; |
| + } |
| + |
| +private: |
| + CompositorWorkerSharedState() {} |
| + ~CompositorWorkerSharedState() {} |
| + |
| + Mutex m_mutex; |
| + OwnPtr<WebThreadSupportingGC> m_thread; |
| + int m_workerCount = 0; |
| + v8::Isolate* m_isolate = nullptr; |
| +}; |
| + |
| +} // namespace |
| + |
| PassRefPtr<CompositorWorkerThread> CompositorWorkerThread::create(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin) |
| { |
| + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWorkerThread::create"); |
| ASSERT(isMainThread()); |
| return adoptRef(new CompositorWorkerThread(workerLoaderProxy, workerObjectProxy, timeOrigin)); |
| } |
| @@ -31,44 +153,65 @@ CompositorWorkerThread::~CompositorWorkerThread() |
| { |
| } |
| +WebThreadSupportingGC* CompositorWorkerThread::sharedBackingThread() |
| +{ |
| + return CompositorWorkerSharedState::instance().compositorWorkerThread(); |
| +} |
| + |
| PassRefPtrWillBeRawPtr<WorkerGlobalScope> CompositorWorkerThread::createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData> startupData) |
| { |
| + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWorkerThread::createWorkerGlobalScope"); |
| return CompositorWorkerGlobalScope::create(this, startupData, m_timeOrigin); |
| } |
| WebThreadSupportingGC& CompositorWorkerThread::backingThread() |
| { |
| - return CompositorWorkerManager::instance()->compositorWorkerThread(); |
| + return *CompositorWorkerSharedState::instance().compositorWorkerThread(); |
| } |
| void CompositorWorkerThread::initializeBackingThread() |
| { |
| - CompositorWorkerManager::instance()->initializeBackingThread(); |
| + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWorkerThread::initializeBackingThread"); |
| + CompositorWorkerSharedState::instance().initializeBackingThread(); |
| } |
| void CompositorWorkerThread::shutdownBackingThread() |
| { |
| - CompositorWorkerManager::instance()->shutdownBackingThread(); |
| + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWorkerThread::shutdownBackingThread"); |
| + CompositorWorkerSharedState::instance().shutdownBackingThread(); |
| } |
| v8::Isolate* CompositorWorkerThread::initializeIsolate() |
| { |
| - return CompositorWorkerManager::instance()->initializeIsolate(); |
| + return CompositorWorkerSharedState::instance().initializeIsolate(); |
| } |
| void CompositorWorkerThread::willDestroyIsolate() |
| { |
| - CompositorWorkerManager::instance()->willDestroyIsolate(); |
| + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWorkerThread::willDestroyIsolate"); |
| + CompositorWorkerSharedState::instance().willDestroyIsolate(); |
| } |
| void CompositorWorkerThread::destroyIsolate() |
| { |
| - CompositorWorkerManager::instance()->destroyIsolate(); |
| + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWorkerThread::destroyIsolate"); |
| + CompositorWorkerSharedState::instance().destroyIsolate(); |
| } |
| void CompositorWorkerThread::terminateV8Execution() |
| { |
| - CompositorWorkerManager::instance()->terminateV8Execution(); |
| + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWorkerThread::terminateV8Execution"); |
| + CompositorWorkerSharedState::instance().terminateV8Execution(); |
| +} |
| + |
| +bool CompositorWorkerThread::hasThreadForTest() |
| +{ |
| + return CompositorWorkerSharedState::instance().hasThreadForTest(); |
| +} |
| + |
| +bool CompositorWorkerThread::hasIsolateForTest() |
| +{ |
| + return CompositorWorkerSharedState::instance().hasIsolateForTest(); |
| } |
| } // namespace blink |