Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: Source/modules/webaudio/AudioContext.cpp

Issue 940963005: Revert of WebAudio: Fix AudioNode leak in a case that AudioNode is not disconnected from the ... (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/modules/webaudio/AudioContext.h ('k') | Source/modules/webaudio/AudioNode.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010, Google Inc. All rights reserved. 2 * Copyright (C) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 : ActiveDOMObject(document) 104 : ActiveDOMObject(document)
105 , m_isStopScheduled(false) 105 , m_isStopScheduled(false)
106 , m_isCleared(false) 106 , m_isCleared(false)
107 , m_isInitialized(false) 107 , m_isInitialized(false)
108 , m_destinationNode(nullptr) 108 , m_destinationNode(nullptr)
109 , m_isResolvingResumePromises(false) 109 , m_isResolvingResumePromises(false)
110 , m_automaticPullNodesNeedUpdating(false) 110 , m_automaticPullNodesNeedUpdating(false)
111 , m_connectionCount(0) 111 , m_connectionCount(0)
112 , m_didInitializeContextGraphMutex(false) 112 , m_didInitializeContextGraphMutex(false)
113 , m_audioThread(0) 113 , m_audioThread(0)
114 , m_lastZombie(nullptr)
115 , m_lastRemovableZombie(nullptr)
116 , m_isOfflineContext(false) 114 , m_isOfflineContext(false)
117 , m_contextState(Suspended) 115 , m_contextState(Suspended)
118 , m_cachedSampleFrame(0) 116 , m_cachedSampleFrame(0)
119 { 117 {
120 m_didInitializeContextGraphMutex = true; 118 m_didInitializeContextGraphMutex = true;
121 m_destinationNode = DefaultAudioDestinationNode::create(this); 119 m_destinationNode = DefaultAudioDestinationNode::create(this);
122 120
123 initialize(); 121 initialize();
124 } 122 }
125 123
126 // Constructor for offline (non-realtime) rendering. 124 // Constructor for offline (non-realtime) rendering.
127 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) 125 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate)
128 : ActiveDOMObject(document) 126 : ActiveDOMObject(document)
129 , m_isStopScheduled(false) 127 , m_isStopScheduled(false)
130 , m_isCleared(false) 128 , m_isCleared(false)
131 , m_isInitialized(false) 129 , m_isInitialized(false)
132 , m_destinationNode(nullptr) 130 , m_destinationNode(nullptr)
133 , m_isResolvingResumePromises(false) 131 , m_isResolvingResumePromises(false)
134 , m_automaticPullNodesNeedUpdating(false) 132 , m_automaticPullNodesNeedUpdating(false)
135 , m_connectionCount(0) 133 , m_connectionCount(0)
136 , m_didInitializeContextGraphMutex(false) 134 , m_didInitializeContextGraphMutex(false)
137 , m_audioThread(0) 135 , m_audioThread(0)
138 , m_lastZombie(nullptr)
139 , m_lastRemovableZombie(nullptr)
140 , m_isOfflineContext(true) 136 , m_isOfflineContext(true)
141 , m_contextState(Suspended) 137 , m_contextState(Suspended)
142 , m_cachedSampleFrame(0) 138 , m_cachedSampleFrame(0)
143 { 139 {
144 m_didInitializeContextGraphMutex = true; 140 m_didInitializeContextGraphMutex = true;
145 // Create a new destination for offline rendering. 141 // Create a new destination for offline rendering.
146 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate); 142 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate);
147 if (m_renderTarget.get()) 143 if (m_renderTarget.get())
148 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get()); 144 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get());
149 145
(...skipping 16 matching lines...) Expand all
166 ASSERT(!m_suspendResolvers.size()); 162 ASSERT(!m_suspendResolvers.size());
167 ASSERT(!m_isResolvingResumePromises); 163 ASSERT(!m_isResolvingResumePromises);
168 ASSERT(!m_resumeResolvers.size()); 164 ASSERT(!m_resumeResolvers.size());
169 } 165 }
170 166
171 void AudioContext::initialize() 167 void AudioContext::initialize()
172 { 168 {
173 if (isInitialized()) 169 if (isInitialized())
174 return; 170 return;
175 171
176 ThreadState::current()->addMarkingTask(this);
177 FFTFrame::initialize(); 172 FFTFrame::initialize();
178 m_listener = AudioListener::create(); 173 m_listener = AudioListener::create();
179 174
180 if (m_destinationNode.get()) { 175 if (m_destinationNode.get()) {
181 m_destinationNode->initialize(); 176 m_destinationNode->initialize();
182 177
183 if (!isOfflineContext()) { 178 if (!isOfflineContext()) {
184 // This starts the audio thread. The destination node's provideInput () method will now be called repeatedly to render audio. 179 // This starts the audio thread. The destination node's provideInput () method will now be called repeatedly to render audio.
185 // Each time provideInput() is called, a portion of the audio stream is rendered. Let's call this time period a "render quantum". 180 // Each time provideInput() is called, a portion of the audio stream is rendered. Let's call this time period a "render quantum".
186 // NOTE: for now default AudioContext does not need an explicit star tRendering() call from JavaScript. 181 // NOTE: for now default AudioContext does not need an explicit star tRendering() call from JavaScript.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 setContextState(Closed); 232 setContextState(Closed);
238 233
239 // Resolve the promise now, if any 234 // Resolve the promise now, if any
240 if (m_closeResolver) 235 if (m_closeResolver)
241 m_closeResolver->resolve(); 236 m_closeResolver->resolve();
242 237
243 ASSERT(m_listener); 238 ASSERT(m_listener);
244 m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); 239 m_listener->waitForHRTFDatabaseLoaderThreadCompletion();
245 240
246 clear(); 241 clear();
247
248 ThreadState::current()->removeMarkingTask(this);
249 if (m_lastZombie)
250 ThreadState::current()->purifyZombies();
251 m_lastZombie = nullptr;
252 m_lastRemovableZombie = nullptr;
253 } 242 }
254 243
255 void AudioContext::stop() 244 void AudioContext::stop()
256 { 245 {
257 // Usually ExecutionContext calls stop twice. 246 // Usually ExecutionContext calls stop twice.
258 if (m_isStopScheduled) 247 if (m_isStopScheduled)
259 return; 248 return;
260 m_isStopScheduled = true; 249 m_isStopScheduled = true;
261 250
262 // Don't call uninitialize() immediately here because the ExecutionContext i s in the middle 251 // Don't call uninitialize() immediately here because the ExecutionContext i s in the middle
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 if (tryLock()) { 978 if (tryLock()) {
990 // Update the channel count mode. 979 // Update the channel count mode.
991 updateChangedChannelCountMode(); 980 updateChangedChannelCountMode();
992 981
993 // Take care of AudioNode tasks where the tryLock() failed previously. 982 // Take care of AudioNode tasks where the tryLock() failed previously.
994 handleDeferredAudioNodeTasks(); 983 handleDeferredAudioNodeTasks();
995 984
996 // Dynamically clean up nodes which are no longer needed. 985 // Dynamically clean up nodes which are no longer needed.
997 derefFinishedSourceNodes(); 986 derefFinishedSourceNodes();
998 987
999 m_lastRemovableZombie = m_lastZombie;
1000
1001 // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutpu ts. 988 // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutpu ts.
1002 handleDirtyAudioSummingJunctions(); 989 handleDirtyAudioSummingJunctions();
1003 handleDirtyAudioNodeOutputs(); 990 handleDirtyAudioNodeOutputs();
1004 991
1005 updateAutomaticPullNodes(); 992 updateAutomaticPullNodes();
1006 resolvePromisesForSuspend(); 993 resolvePromisesForSuspend();
1007 994
1008 unlock(); 995 unlock();
1009 } 996 }
1010 } 997 }
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 } 1274 }
1288 } 1275 }
1289 1276
1290 DEFINE_TRACE(AudioContext) 1277 DEFINE_TRACE(AudioContext)
1291 { 1278 {
1292 visitor->trace(m_closeResolver); 1279 visitor->trace(m_closeResolver);
1293 visitor->trace(m_offlineResolver); 1280 visitor->trace(m_offlineResolver);
1294 visitor->trace(m_renderTarget); 1281 visitor->trace(m_renderTarget);
1295 visitor->trace(m_destinationNode); 1282 visitor->trace(m_destinationNode);
1296 visitor->trace(m_listener); 1283 visitor->trace(m_listener);
1297 visitor->trace(m_referencedNodes); 1284 // trace() can be called in AudioContext constructor, and
1285 // m_contextGraphMutex might be unavailable.
1286 if (m_didInitializeContextGraphMutex) {
1287 AutoLocker lock(this);
1288 visitor->trace(m_referencedNodes);
1289 } else {
1290 visitor->trace(m_referencedNodes);
1291 }
1298 visitor->trace(m_resumeResolvers); 1292 visitor->trace(m_resumeResolvers);
1299 visitor->trace(m_suspendResolvers); 1293 visitor->trace(m_suspendResolvers);
1300 visitor->trace(m_liveNodes); 1294 visitor->trace(m_liveNodes);
1301 visitor->trace(m_liveAudioSummingJunctions); 1295 visitor->trace(m_liveAudioSummingJunctions);
1302 RefCountedGarbageCollectedEventTargetWithInlineData<AudioContext>::trace(vis itor); 1296 RefCountedGarbageCollectedEventTargetWithInlineData<AudioContext>::trace(vis itor);
1303 ActiveDOMObject::trace(visitor); 1297 ActiveDOMObject::trace(visitor);
1304 } 1298 }
1305 1299
1306 void AudioContext::addChangedChannelCountMode(AudioNode* node) 1300 void AudioContext::addChangedChannelCountMode(AudioNode* node)
1307 { 1301 {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 1358
1365 // Stop the audio context. This will stop the destination node from pulling audio anymore. And 1359 // Stop the audio context. This will stop the destination node from pulling audio anymore. And
1366 // since we have disconnected the destination from the audio graph, and thus has no references, 1360 // since we have disconnected the destination from the audio graph, and thus has no references,
1367 // the destination node can GCed if JS has no references. stop() will also r esolve the Promise 1361 // the destination node can GCed if JS has no references. stop() will also r esolve the Promise
1368 // created here. 1362 // created here.
1369 stop(); 1363 stop();
1370 1364
1371 return promise; 1365 return promise;
1372 } 1366 }
1373 1367
1374 void AudioContext::setLastZombie(void* object)
1375 {
1376 ASSERT(isGraphOwner());
1377 m_lastZombie = object;
1378 }
1379
1380 void AudioContext::willStartMarking(ThreadState& threadState)
1381 {
1382 lock();
1383 if (!m_lastRemovableZombie)
1384 return;
1385 if (m_lastZombie != m_lastRemovableZombie)
1386 return;
1387 threadState.purifyZombies();
1388 m_lastZombie = nullptr;
1389 m_lastRemovableZombie = nullptr;
1390 }
1391
1392 void AudioContext::didFinishMarking(ThreadState&)
1393 {
1394 unlock();
1395 }
1396
1397 } // namespace blink 1368 } // namespace blink
1398 1369
1399 #endif // ENABLE(WEB_AUDIO) 1370 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/modules/webaudio/AudioContext.h ('k') | Source/modules/webaudio/AudioNode.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698