Index: third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp |
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp |
index 32f1f5f2a9dd8b5195da38fbe02b435007eaf7aa..e15549cfc9453e021b4c8eab71a605d00e807af4 100644 |
--- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp |
+++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp |
@@ -173,7 +173,23 @@ void OfflineAudioDestinationHandler::StartOfflineRendering() { |
void OfflineAudioDestinationHandler::DoOfflineRendering() { |
DCHECK(!IsMainThread()); |
- unsigned number_of_channels = render_target_->numberOfChannels(); |
+ unsigned number_of_channels; |
+ Vector<float*> destinations; |
+ { |
+ // Main thread GCs cannot happen while we're reading out channel |
+ // data. Detect that condition by trying to take the cross-thread |
+ // persistent lock which is held while a GC runs. If the lock is |
+ // already held, simply delay rendering until the next quantum. |
+ CrossThreadPersistentRegion::LockScope gc_lock( |
+ ProcessHeap::GetCrossThreadPersistentRegion(), true); |
+ if (!gc_lock.HasLock()) |
+ return; |
+ |
+ number_of_channels = render_target_->numberOfChannels(); |
+ destinations.ReserveInitialCapacity(number_of_channels); |
+ for (unsigned i = 0; i < number_of_channels; ++i) |
+ destinations.push_back(render_target_->getChannelData(i).View()->Data()); |
+ } |
// Reset the suspend flag. |
should_suspend_ = false; |
@@ -198,9 +214,7 @@ void OfflineAudioDestinationHandler::DoOfflineRendering() { |
for (unsigned channel_index = 0; channel_index < number_of_channels; |
++channel_index) { |
const float* source = render_bus_->Channel(channel_index)->Data(); |
- float* destination = |
- render_target_->getChannelData(channel_index).View()->Data(); |
- memcpy(destination + frames_processed_, source, |
+ memcpy(destinations[channel_index] + frames_processed_, source, |
sizeof(float) * frames_available_to_copy); |
} |