Commit a989f825 authored by Hajime Hoshi's avatar Hajime Hoshi Committed by Commit Bot

Avoid calling Context()->GetExecutionContext() on non-main threads in webaudio

Checking the existence of execution context is not thread safe. Instead,
let's check it on the handler sides (main thread).

Bug: 696905
Change-Id: I68a05ef9e32837f74ef1772d66631bfd104c7d5e
Reviewed-on: https://chromium-review.googlesource.com/746721Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarHongchan Choi <hongchan@chromium.org>
Reviewed-by: default avatarRaymond Toy <rtoy@chromium.org>
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#512850}
parent 1b8fb65c
...@@ -231,16 +231,16 @@ void AudioScheduledSourceHandler::FinishWithoutOnEnded() { ...@@ -231,16 +231,16 @@ void AudioScheduledSourceHandler::FinishWithoutOnEnded() {
void AudioScheduledSourceHandler::Finish() { void AudioScheduledSourceHandler::Finish() {
FinishWithoutOnEnded(); FinishWithoutOnEnded();
if (Context()->GetExecutionContext()) { task_runner_->PostTask(
task_runner_->PostTask( BLINK_FROM_HERE,
BLINK_FROM_HERE, CrossThreadBind(&AudioScheduledSourceHandler::NotifyEnded,
CrossThreadBind(&AudioScheduledSourceHandler::NotifyEnded, WrapRefCounted(this)));
WrapRefCounted(this)));
}
} }
void AudioScheduledSourceHandler::NotifyEnded() { void AudioScheduledSourceHandler::NotifyEnded() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
if (!Context() || !Context()->GetExecutionContext())
return;
if (GetNode()) if (GetNode())
GetNode()->DispatchEvent(Event::Create(EventTypeNames::ended)); GetNode()->DispatchEvent(Event::Create(EventTypeNames::ended));
} }
......
...@@ -203,12 +203,10 @@ void MediaElementAudioSourceHandler::Process(size_t number_of_frames) { ...@@ -203,12 +203,10 @@ void MediaElementAudioSourceHandler::Process(size_t number_of_frames) {
// Print a CORS message, but just once for each change in the current // Print a CORS message, but just once for each change in the current
// media element source, and only if we have a document to print to. // media element source, and only if we have a document to print to.
maybe_print_cors_message_ = false; maybe_print_cors_message_ = false;
if (Context()->GetExecutionContext()) { task_runner_->PostTask(
task_runner_->PostTask( BLINK_FROM_HERE,
BLINK_FROM_HERE, CrossThreadBind(&MediaElementAudioSourceHandler::PrintCORSMessage,
CrossThreadBind(&MediaElementAudioSourceHandler::PrintCORSMessage, WrapRefCounted(this), current_src_string_));
WrapRefCounted(this), current_src_string_));
}
} }
output_bus->Zero(); output_bus->Zero();
} }
......
...@@ -254,30 +254,26 @@ void OfflineAudioDestinationHandler::SuspendOfflineRendering() { ...@@ -254,30 +254,26 @@ void OfflineAudioDestinationHandler::SuspendOfflineRendering() {
DCHECK(!IsMainThread()); DCHECK(!IsMainThread());
// The actual rendering has been suspended. Notify the context. // The actual rendering has been suspended. Notify the context.
if (Context()->GetExecutionContext()) { task_runner_->PostTask(
task_runner_->PostTask( BLINK_FROM_HERE,
BLINK_FROM_HERE, CrossThreadBind(&OfflineAudioDestinationHandler::NotifySuspend,
CrossThreadBind(&OfflineAudioDestinationHandler::NotifySuspend, WrapRefCounted(this), Context()->CurrentSampleFrame()));
WrapRefCounted(this), Context()->CurrentSampleFrame()));
}
} }
void OfflineAudioDestinationHandler::FinishOfflineRendering() { void OfflineAudioDestinationHandler::FinishOfflineRendering() {
DCHECK(!IsMainThread()); DCHECK(!IsMainThread());
// The actual rendering has been completed. Notify the context. // The actual rendering has been completed. Notify the context.
if (Context()->GetExecutionContext()) { task_runner_->PostTask(
task_runner_->PostTask( BLINK_FROM_HERE,
BLINK_FROM_HERE, CrossThreadBind(&OfflineAudioDestinationHandler::NotifyComplete,
CrossThreadBind(&OfflineAudioDestinationHandler::NotifyComplete, WrapRefCounted(this)));
WrapRefCounted(this)));
}
} }
void OfflineAudioDestinationHandler::NotifySuspend(size_t frame) { void OfflineAudioDestinationHandler::NotifySuspend(size_t frame) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
if (Context()) if (Context() && Context()->GetExecutionContext())
Context()->ResolveSuspendOnMainThread(frame); Context()->ResolveSuspendOnMainThread(frame);
} }
...@@ -288,7 +284,7 @@ void OfflineAudioDestinationHandler::NotifyComplete() { ...@@ -288,7 +284,7 @@ void OfflineAudioDestinationHandler::NotifyComplete() {
render_thread_.reset(); render_thread_.reset();
// The OfflineAudioContext might be gone. // The OfflineAudioContext might be gone.
if (Context()) if (Context() && Context()->GetExecutionContext())
Context()->FireCompletionEvent(); Context()->FireCompletionEvent();
} }
......
...@@ -213,7 +213,7 @@ void ScriptProcessorHandler::Process(size_t frames_to_process) { ...@@ -213,7 +213,7 @@ void ScriptProcessorHandler::Process(size_t frames_to_process) {
// We're late in handling the previous request. The main thread must be // We're late in handling the previous request. The main thread must be
// very busy. The best we can do is clear out the buffer ourself here. // very busy. The best we can do is clear out the buffer ourself here.
output_buffer->Zero(); output_buffer->Zero();
} else if (Context()->GetExecutionContext()) { } else {
// With the realtime context, execute the script code asynchronously // With the realtime context, execute the script code asynchronously
// and do not wait. // and do not wait.
if (Context()->HasRealtimeConstraint()) { if (Context()->HasRealtimeConstraint()) {
...@@ -249,6 +249,9 @@ void ScriptProcessorHandler::Process(size_t frames_to_process) { ...@@ -249,6 +249,9 @@ void ScriptProcessorHandler::Process(size_t frames_to_process) {
void ScriptProcessorHandler::FireProcessEvent(unsigned double_buffer_index) { void ScriptProcessorHandler::FireProcessEvent(unsigned double_buffer_index) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
if (!Context() || !Context()->GetExecutionContext())
return;
DCHECK_LT(double_buffer_index, 2u); DCHECK_LT(double_buffer_index, 2u);
if (double_buffer_index > 1) if (double_buffer_index > 1)
return; return;
...@@ -260,7 +263,7 @@ void ScriptProcessorHandler::FireProcessEvent(unsigned double_buffer_index) { ...@@ -260,7 +263,7 @@ void ScriptProcessorHandler::FireProcessEvent(unsigned double_buffer_index) {
return; return;
// Avoid firing the event if the document has already gone away. // Avoid firing the event if the document has already gone away.
if (GetNode() && Context() && Context()->GetExecutionContext()) { if (GetNode()) {
// This synchronizes with process(). // This synchronizes with process().
MutexLocker process_locker(process_event_lock_); MutexLocker process_locker(process_event_lock_);
...@@ -282,6 +285,9 @@ void ScriptProcessorHandler::FireProcessEventForOfflineAudioContext( ...@@ -282,6 +285,9 @@ void ScriptProcessorHandler::FireProcessEventForOfflineAudioContext(
WaitableEvent* waitable_event) { WaitableEvent* waitable_event) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
if (!Context() || !Context()->GetExecutionContext())
return;
DCHECK_LT(double_buffer_index, 2u); DCHECK_LT(double_buffer_index, 2u);
if (double_buffer_index > 1) { if (double_buffer_index > 1) {
waitable_event->Signal(); waitable_event->Signal();
...@@ -296,7 +302,7 @@ void ScriptProcessorHandler::FireProcessEventForOfflineAudioContext( ...@@ -296,7 +302,7 @@ void ScriptProcessorHandler::FireProcessEventForOfflineAudioContext(
return; return;
} }
if (GetNode() && Context() && Context()->GetExecutionContext()) { if (GetNode()) {
// We do not need a process lock here because the offline render thread // We do not need a process lock here because the offline render thread
// is locked by the waitable event. // is locked by the waitable event.
double playback_time = (Context()->CurrentSampleFrame() + buffer_size_) / double playback_time = (Context()->CurrentSampleFrame() + buffer_size_) /
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment