Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "modules/webaudio/AudioWorkletThread.h" | |
| 6 | |
| 7 #include "core/workers/WorkerBackingThread.h" | |
| 8 #include "core/workers/WorkerThreadStartupData.h" | |
| 9 #include "modules/webaudio/AudioWorkletGlobalScope.h" | |
| 10 #include "platform/CrossThreadFunctional.h" | |
| 11 #include "platform/TraceEvent.h" | |
| 12 #include "platform/WaitableEvent.h" | |
| 13 #include "platform/WebThreadSupportingGC.h" | |
| 14 #include "platform/weborigin/SecurityOrigin.h" | |
| 15 #include "public/platform/Platform.h" | |
| 16 #include "wtf/Assertions.h" | |
| 17 #include "wtf/PtrUtil.h" | |
| 18 #include <memory> | |
| 19 | |
| 20 namespace blink { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 class BackingThreadHolder { | |
|
haraken
2016/09/30 00:18:38
Can we share the implementation with BackingThread
haraken
2016/09/30 00:18:38
Redundant indentation.
hongchan
2016/10/11 23:42:38
Done.
| |
| 25 public: | |
| 26 static BackingThreadHolder* instance() | |
| 27 { | |
| 28 MutexLocker locker(holderInstanceMutex()); | |
| 29 return s_instance; | |
| 30 } | |
| 31 | |
| 32 static void ensureInstance() | |
| 33 { | |
| 34 if (!s_instance) | |
| 35 s_instance = new BackingThreadHolder; | |
| 36 } | |
| 37 | |
| 38 static void clear() | |
| 39 { | |
| 40 MutexLocker locker(holderInstanceMutex()); | |
| 41 if (s_instance) { | |
| 42 s_instance->shutdownAndWait(); | |
| 43 delete s_instance; | |
| 44 s_instance = nullptr; | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 static void createForTest() | |
| 49 { | |
| 50 MutexLocker locker(holderInstanceMutex()); | |
| 51 DCHECK_EQ(nullptr, s_instance); | |
| 52 s_instance = new BackingThreadHolder(WorkerBackingThread::createForT est("AudioWorkletThread", BlinkGC::PerThreadHeapMode)); | |
| 53 } | |
| 54 | |
| 55 WorkerBackingThread* thread() { return m_thread.get(); } | |
| 56 | |
| 57 private: | |
| 58 BackingThreadHolder(std::unique_ptr<WorkerBackingThread> useBackingThrea d = nullptr) | |
| 59 : m_thread(useBackingThread ? std::move(useBackingThread) : WorkerBa ckingThread::create("AudioWorkletThread", BlinkGC::PerThreadHeapMode)) | |
| 60 { | |
| 61 DCHECK(isMainThread()); | |
| 62 m_thread->backingThread().postTask(BLINK_FROM_HERE, crossThreadBind( &BackingThreadHolder::initializeOnThread, crossThreadUnretained(this))); | |
| 63 } | |
| 64 | |
| 65 static Mutex& holderInstanceMutex() | |
| 66 { | |
| 67 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, holderMutex, new Mutex); | |
| 68 return holderMutex; | |
| 69 } | |
| 70 | |
| 71 void initializeOnThread() | |
| 72 { | |
| 73 MutexLocker locker(holderInstanceMutex()); | |
| 74 DCHECK(!m_initialized); | |
| 75 m_thread->initialize(); | |
| 76 m_initialized = true; | |
| 77 } | |
| 78 | |
| 79 void shutdownAndWait() | |
| 80 { | |
| 81 DCHECK(isMainThread()); | |
| 82 WaitableEvent doneEvent; | |
| 83 m_thread->backingThread().postTask(BLINK_FROM_HERE, crossThreadBind( &BackingThreadHolder::shutdownOnThread, crossThreadUnretained(this), crossThread Unretained(&doneEvent))); | |
| 84 doneEvent.wait(); | |
| 85 } | |
| 86 | |
| 87 void shutdownOnThread(WaitableEvent* doneEvent) | |
| 88 { | |
| 89 m_thread->shutdown(); | |
| 90 doneEvent->signal(); | |
| 91 } | |
| 92 | |
| 93 std::unique_ptr<WorkerBackingThread> m_thread; | |
| 94 bool m_initialized = false; | |
| 95 | |
| 96 static BackingThreadHolder* s_instance; | |
| 97 }; | |
| 98 | |
| 99 BackingThreadHolder* BackingThreadHolder::s_instance = nullptr; | |
| 100 | |
| 101 } // namespace | |
| 102 | |
| 103 std::unique_ptr<AudioWorkletThread> AudioWorkletThread::create(PassRefPtr<Worker LoaderProxy> workerLoaderProxy, WorkerReportingProxy& workerReportingProxy) | |
| 104 { | |
| 105 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("audio-worklet"), "AudioWorkletThread ::create"); | |
| 106 DCHECK(isMainThread()); | |
| 107 return wrapUnique(new AudioWorkletThread(std::move(workerLoaderProxy), worke rReportingProxy)); | |
| 108 } | |
| 109 | |
| 110 AudioWorkletThread::AudioWorkletThread(PassRefPtr<WorkerLoaderProxy> workerLoade rProxy, WorkerReportingProxy& workerReportingProxy) | |
| 111 : WorkerThread(std::move(workerLoaderProxy), workerReportingProxy) | |
| 112 { | |
| 113 } | |
| 114 | |
| 115 AudioWorkletThread::~AudioWorkletThread() | |
| 116 { | |
| 117 } | |
| 118 | |
| 119 WorkerBackingThread& AudioWorkletThread::workerBackingThread() | |
| 120 { | |
| 121 return *BackingThreadHolder::instance()->thread(); | |
| 122 } | |
| 123 | |
| 124 void collectAllGarbageOnAudioWorkletThread(WaitableEvent* doneEvent) | |
| 125 { | |
| 126 blink::ThreadState::current()->collectAllGarbage(); | |
| 127 doneEvent->signal(); | |
| 128 } | |
| 129 | |
| 130 void AudioWorkletThread::collectAllGarbage() | |
| 131 { | |
| 132 DCHECK(isMainThread()); | |
| 133 WaitableEvent doneEvent; | |
| 134 BackingThreadHolder* instance = BackingThreadHolder::instance(); | |
| 135 if (!instance) | |
| 136 return; | |
| 137 instance->thread()->backingThread().postTask(BLINK_FROM_HERE, crossThreadBin d(&collectAllGarbageOnAudioWorkletThread, crossThreadUnretained(&doneEvent))); | |
| 138 doneEvent.wait(); | |
| 139 } | |
| 140 | |
| 141 void AudioWorkletThread::ensureSharedBackingThread() | |
| 142 { | |
| 143 DCHECK(isMainThread()); | |
| 144 BackingThreadHolder::ensureInstance(); | |
| 145 } | |
| 146 | |
| 147 void AudioWorkletThread::clearSharedBackingThread() | |
| 148 { | |
| 149 DCHECK(isMainThread()); | |
| 150 BackingThreadHolder::clear(); | |
| 151 } | |
| 152 | |
| 153 void AudioWorkletThread::createSharedBackingThreadForTest() | |
| 154 { | |
| 155 BackingThreadHolder::createForTest(); | |
| 156 } | |
| 157 | |
| 158 WorkerOrWorkletGlobalScope* AudioWorkletThread::createWorkerGlobalScope(std::uni que_ptr<WorkerThreadStartupData> startupData) | |
| 159 { | |
| 160 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("audio-worklet"), "AudioWorkletThread ::createWorkerGlobalScope"); | |
| 161 | |
| 162 RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(startupData-> m_scriptURL); | |
| 163 if (startupData->m_starterOriginPrivilegeData) | |
| 164 securityOrigin->transferPrivilegesFrom(std::move(startupData->m_starterO riginPrivilegeData)); | |
| 165 | |
| 166 return AudioWorkletGlobalScope::create(startupData->m_scriptURL, startupData ->m_userAgent, securityOrigin.release(), this->isolate(), this); | |
| 167 } | |
| 168 | |
| 169 } // namespace blink | |
| OLD | NEW |