Commit 4f309b86 authored by Hongchan Choi's avatar Hongchan Choi Committed by Commit Bot

Use SupportWeakPtr in OfflineAudioDestinationHandler

OfflineAudioDestinationHandler's render thread notifies the
main thread when the rendering state changes. In this process,
the associated audio context can be deleted when a posted task
is performed sometime later in the task runner's queue.

By using WeakPtr, the task runner will not perform a scheduled task
in the queue when the target object is no longer valid.

Bug: 1095584
Test: Locally confirmed that the repro case does not crash after 30 min.
Change-Id: Ic1814b97f8d9a8d1027ef04f475112874cfa8137
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2285473Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarRaymond Toy <rtoy@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#786381}
parent e6e31d2c
......@@ -51,17 +51,14 @@ OfflineAudioDestinationHandler::OfflineAudioDestinationHandler(
frames_to_process_(frames_to_process),
is_rendering_started_(false),
number_of_channels_(number_of_channels),
sample_rate_(sample_rate) {
channel_count_ = number_of_channels;
sample_rate_(sample_rate),
main_thread_task_runner_(Context()->GetExecutionContext()->GetTaskRunner(
TaskType::kInternalMedia)) {
DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
channel_count_ = number_of_channels;
SetInternalChannelCountMode(kExplicit);
SetInternalChannelInterpretation(AudioBus::kSpeakers);
if (Context()->GetExecutionContext()) {
main_thread_task_runner_ = Context()->GetExecutionContext()->GetTaskRunner(
TaskType::kMiscPlatformAPI);
DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
}
}
scoped_refptr<OfflineAudioDestinationHandler>
......@@ -218,7 +215,7 @@ void OfflineAudioDestinationHandler::SuspendOfflineRendering() {
PostCrossThreadTask(
*main_thread_task_runner_, FROM_HERE,
CrossThreadBindOnce(&OfflineAudioDestinationHandler::NotifySuspend,
WrapRefCounted(this),
GetWeakPtr(),
Context()->CurrentSampleFrame()));
}
......@@ -229,7 +226,7 @@ void OfflineAudioDestinationHandler::FinishOfflineRendering() {
PostCrossThreadTask(
*main_thread_task_runner_, FROM_HERE,
CrossThreadBindOnce(&OfflineAudioDestinationHandler::NotifyComplete,
WrapRefCounted(this)));
GetWeakPtr()));
}
void OfflineAudioDestinationHandler::NotifySuspend(size_t frame) {
......
......@@ -28,6 +28,7 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_destination_node.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_context.h"
......@@ -124,6 +125,17 @@ class OfflineAudioDestinationHandler final : public AudioDestinationHandler {
// from AudioWorkletThread will be used until the rendering is finished.
void PrepareTaskRunnerForRendering();
// For cross-thread posting, this object uses two different targets.
// 1. rendering thread -> main thread: WeakPtr
// When the main thread starts deleting this object, a task posted with
// a WeakPtr from the rendering thread will be cancelled.
// 2. main thread -> rendering thread: scoped_refptr
// |render_thread_| is owned by this object, so it is safe to target with
// WrapRefCounted() instead of GetWeakPtr().
base::WeakPtr<OfflineAudioDestinationHandler> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// This AudioHandler renders into this SharedAudioBuffer.
std::unique_ptr<SharedAudioBuffer> shared_render_target_;
// Temporary AudioBus for each render quantum.
......@@ -148,6 +160,8 @@ class OfflineAudioDestinationHandler final : public AudioDestinationHandler {
scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
base::WeakPtrFactory<OfflineAudioDestinationHandler> weak_factory_{this};
};
class OfflineAudioDestinationNode final : public AudioDestinationNode {
......
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