OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/compositorworker/CompositorWorkerThread.h" | 5 #include "modules/compositorworker/CompositorWorkerThread.h" |
6 | 6 |
7 #include "bindings/core/v8/V8GCController.h" | 7 #include "bindings/core/v8/V8GCController.h" |
8 #include "bindings/core/v8/V8Initializer.h" | 8 #include "bindings/core/v8/V8Initializer.h" |
9 #include "core/workers/InProcessWorkerObjectProxy.h" | 9 #include "core/workers/InProcessWorkerObjectProxy.h" |
10 #include "core/workers/WorkerBackingThread.h" | 10 #include "core/workers/WorkerBackingThread.h" |
11 #include "core/workers/WorkerThreadStartupData.h" | 11 #include "core/workers/WorkerThreadStartupData.h" |
12 #include "modules/compositorworker/CompositorWorkerGlobalScope.h" | 12 #include "modules/compositorworker/CompositorWorkerGlobalScope.h" |
13 #include "platform/ThreadSafeFunctional.h" | 13 #include "platform/ThreadSafeFunctional.h" |
14 #include "platform/TraceEvent.h" | 14 #include "platform/TraceEvent.h" |
| 15 #include "platform/WaitableEvent.h" |
| 16 #include "platform/WebThreadSupportingGC.h" |
15 #include "public/platform/Platform.h" | 17 #include "public/platform/Platform.h" |
16 | 18 |
17 namespace blink { | 19 namespace blink { |
18 | 20 |
19 namespace { | 21 namespace { |
20 | 22 |
21 // This is a singleton class holding the compositor worker thread in this | 23 // This is a singleton class holding the compositor worker thread in this |
22 // renderrer process. BackingThreadHolst::m_thread will never be cleared, | 24 // renderer process. BackingThreadHolder::m_thread is cleared by |
23 // but Oilpan and V8 are detached from the thread when the last compositor | 25 // ModulesInitializer::shutdown. |
24 // worker thread is gone. | |
25 // See WorkerThread::terminateAndWaitForAllWorkers for the process shutdown | 26 // See WorkerThread::terminateAndWaitForAllWorkers for the process shutdown |
26 // case. | 27 // case. |
27 class BackingThreadHolder { | 28 class BackingThreadHolder { |
28 public: | 29 public: |
29 static BackingThreadHolder& instance() | 30 static BackingThreadHolder& instance() |
30 { | 31 { |
31 DEFINE_THREAD_SAFE_STATIC_LOCAL(BackingThreadHolder, holder, new Backing
ThreadHolder); | 32 MutexLocker locker(holderInstanceMutex()); |
32 return holder; | 33 return *s_instance; |
| 34 } |
| 35 |
| 36 static void ensureInstance() |
| 37 { |
| 38 if (!s_instance) |
| 39 s_instance = new BackingThreadHolder; |
| 40 } |
| 41 |
| 42 static void terminateExecution() |
| 43 { |
| 44 MutexLocker locker(holderInstanceMutex()); |
| 45 if (s_instance && s_instance->m_initialized) { |
| 46 s_instance->thread()->isolate()->TerminateExecution(); |
| 47 s_instance->m_terminatingExecution = true; |
| 48 } |
| 49 } |
| 50 |
| 51 static void clear() |
| 52 { |
| 53 MutexLocker locker(holderInstanceMutex()); |
| 54 if (s_instance) { |
| 55 DCHECK(!s_instance->m_initialized || s_instance->m_terminatingExecut
ion); |
| 56 s_instance->shutdownAndWait(); |
| 57 delete s_instance; |
| 58 s_instance = nullptr; |
| 59 } |
| 60 } |
| 61 |
| 62 static void createForTest() |
| 63 { |
| 64 MutexLocker locker(holderInstanceMutex()); |
| 65 DCHECK_EQ(nullptr, s_instance); |
| 66 s_instance = new BackingThreadHolder(WorkerBackingThread::createForTest(
Platform::current()->compositorThread())); |
33 } | 67 } |
34 | 68 |
35 WorkerBackingThread* thread() { return m_thread.get(); } | 69 WorkerBackingThread* thread() { return m_thread.get(); } |
36 void resetForTest() | 70 |
| 71 private: |
| 72 BackingThreadHolder(PassOwnPtr<WorkerBackingThread> useBackingThread = nullp
tr) |
| 73 : m_thread(useBackingThread ? std::move(useBackingThread) : WorkerBackin
gThread::create(Platform::current()->compositorThread())) |
37 { | 74 { |
38 ASSERT(!m_thread || (m_thread->workerScriptCount() == 0)); | 75 DCHECK(isMainThread()); |
39 m_thread = nullptr; | 76 m_thread->backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&Back
ingThreadHolder::initializeOnThread, AllowCrossThreadAccess(this))); |
40 m_thread = WorkerBackingThread::createForTest(Platform::current()->compo
sitorThread()); | |
41 } | 77 } |
42 | 78 |
43 private: | 79 static Mutex& holderInstanceMutex() |
44 BackingThreadHolder() : m_thread(WorkerBackingThread::create(Platform::curre
nt()->compositorThread())) {} | 80 { |
| 81 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, holderMutex, new Mutex); |
| 82 return holderMutex; |
| 83 } |
| 84 |
| 85 void initializeOnThread() |
| 86 { |
| 87 MutexLocker locker(holderInstanceMutex()); |
| 88 DCHECK_EQ(0u, m_thread->workerScriptCount()) << "BackingThreadHolder sho
uld be the first to attach to WorkerBackingThread"; |
| 89 m_thread->attach(); |
| 90 m_initialized = true; |
| 91 } |
| 92 |
| 93 void shutdownAndWait() |
| 94 { |
| 95 DCHECK(isMainThread()); |
| 96 WaitableEvent doneEvent; |
| 97 m_thread->backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&Back
ingThreadHolder::shutdownOnThread, AllowCrossThreadAccess(this), AllowCrossThrea
dAccess(&doneEvent))); |
| 98 doneEvent.wait(); |
| 99 } |
| 100 |
| 101 void shutdownOnThread(WaitableEvent* doneEvent) |
| 102 { |
| 103 DCHECK_EQ(1u, m_thread->workerScriptCount()) << "BackingThreadHolder sho
uld be the last to detach from WorkerBackingThread"; |
| 104 m_thread->detach(); |
| 105 doneEvent->signal(); |
| 106 } |
45 | 107 |
46 OwnPtr<WorkerBackingThread> m_thread; | 108 OwnPtr<WorkerBackingThread> m_thread; |
| 109 bool m_terminatingExecution = false; |
| 110 bool m_initialized = false; |
| 111 |
| 112 static BackingThreadHolder* s_instance; |
47 }; | 113 }; |
48 | 114 |
| 115 BackingThreadHolder* BackingThreadHolder::s_instance = nullptr; |
| 116 |
49 } // namespace | 117 } // namespace |
50 | 118 |
51 PassOwnPtr<CompositorWorkerThread> CompositorWorkerThread::create(PassRefPtr<Wor
kerLoaderProxy> workerLoaderProxy, InProcessWorkerObjectProxy& workerObjectProxy
, double timeOrigin) | 119 PassOwnPtr<CompositorWorkerThread> CompositorWorkerThread::create(PassRefPtr<Wor
kerLoaderProxy> workerLoaderProxy, InProcessWorkerObjectProxy& workerObjectProxy
, double timeOrigin) |
52 { | 120 { |
53 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWork
erThread::create"); | 121 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWork
erThread::create"); |
54 ASSERT(isMainThread()); | 122 ASSERT(isMainThread()); |
55 return adoptPtr(new CompositorWorkerThread(workerLoaderProxy, workerObjectPr
oxy, timeOrigin)); | 123 return adoptPtr(new CompositorWorkerThread(workerLoaderProxy, workerObjectPr
oxy, timeOrigin)); |
56 } | 124 } |
57 | 125 |
58 CompositorWorkerThread::CompositorWorkerThread(PassRefPtr<WorkerLoaderProxy> wor
kerLoaderProxy, InProcessWorkerObjectProxy& workerObjectProxy, double timeOrigin
) | 126 CompositorWorkerThread::CompositorWorkerThread(PassRefPtr<WorkerLoaderProxy> wor
kerLoaderProxy, InProcessWorkerObjectProxy& workerObjectProxy, double timeOrigin
) |
(...skipping 11 matching lines...) Expand all Loading... |
70 { | 138 { |
71 return *BackingThreadHolder::instance().thread(); | 139 return *BackingThreadHolder::instance().thread(); |
72 } | 140 } |
73 | 141 |
74 WorkerGlobalScope*CompositorWorkerThread::createWorkerGlobalScope(PassOwnPtr<Wor
kerThreadStartupData> startupData) | 142 WorkerGlobalScope*CompositorWorkerThread::createWorkerGlobalScope(PassOwnPtr<Wor
kerThreadStartupData> startupData) |
75 { | 143 { |
76 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWork
erThread::createWorkerGlobalScope"); | 144 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CompositorWork
erThread::createWorkerGlobalScope"); |
77 return CompositorWorkerGlobalScope::create(this, std::move(startupData), m_t
imeOrigin); | 145 return CompositorWorkerGlobalScope::create(this, std::move(startupData), m_t
imeOrigin); |
78 } | 146 } |
79 | 147 |
80 void CompositorWorkerThread::resetSharedBackingThreadForTest() | 148 void CompositorWorkerThread::ensureSharedBackingThread() |
81 { | 149 { |
82 BackingThreadHolder::instance().resetForTest(); | 150 DCHECK(isMainThread()); |
| 151 BackingThreadHolder::ensureInstance(); |
| 152 } |
| 153 |
| 154 void CompositorWorkerThread::terminateExecution() |
| 155 { |
| 156 DCHECK(isMainThread()); |
| 157 BackingThreadHolder::terminateExecution(); |
| 158 } |
| 159 |
| 160 void CompositorWorkerThread::clearSharedBackingThread() |
| 161 { |
| 162 DCHECK(isMainThread()); |
| 163 BackingThreadHolder::clear(); |
| 164 } |
| 165 |
| 166 void CompositorWorkerThread::createSharedBackingThreadForTest() |
| 167 { |
| 168 BackingThreadHolder::createForTest(); |
83 } | 169 } |
84 | 170 |
85 } // namespace blink | 171 } // namespace blink |
OLD | NEW |