Index: media/audio/audio_manager.cc |
diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc |
index 5d5f3b3a63337dd1df6fb307a6a17f046529704b..821407c720dc70546761e67284229f4ff8e7c926 100644 |
--- a/media/audio/audio_manager.cc |
+++ b/media/audio/audio_manager.cc |
@@ -258,11 +258,15 @@ base::LazyInstance<AudioManagerHelper>::Leaky g_helper = |
// Forward declaration of the platform specific AudioManager factory function. |
AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory); |
-AudioManager::AudioManager() {} |
+AudioManager::AudioManager( |
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner) |
+ : task_runner_(task_runner), worker_task_runner_(worker_task_runner) { |
+ g_last_created = this; |
+} |
AudioManager::~AudioManager() { |
- CHECK(!g_last_created || g_last_created == this); |
- g_last_created = nullptr; |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
} |
// static |
@@ -283,13 +287,10 @@ void AudioManager::ResetFactoryForTesting() { |
// static |
AudioManager* AudioManager::Create(AudioLogFactory* audio_log_factory) { |
- CHECK(!g_last_created); |
if (g_audio_manager_factory) |
- g_last_created = g_audio_manager_factory->CreateInstance(audio_log_factory); |
+ return g_audio_manager_factory->CreateInstance(audio_log_factory); |
else |
- g_last_created = CreateAudioManager(audio_log_factory); |
- |
- return g_last_created; |
+ return CreateAudioManager(audio_log_factory); |
} |
// static |
@@ -316,6 +317,27 @@ AudioManager* AudioManager::CreateForTesting() { |
} |
// static |
+void AudioManager::Destroy(AudioManager* instance) { |
+ CHECK(instance); |
+ CHECK_EQ(g_last_created, instance); |
+ |
+ // AudioManager must be destroyed on the audio thread. |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
+ instance->GetTaskRunner(); |
+ if (task_runner->BelongsToCurrentThread()) { |
+ delete instance; |
+ } else { |
+ task_runner->DeleteSoon(FROM_HERE, instance); |
+ } |
+ |
+ // We reset g_last_created here instead of in the destructor of AudioManager |
+ // to allow construction of another AudioManager while the current instance |
+ // is being destroyed. This overlap does not happen in production - only in |
+ // unittests. |
+ g_last_created = nullptr; |
+} |
+ |
+// static |
void AudioManager::EnableCrashKeyLoggingForAudioThreadHangs() { |
CHECK(!g_last_created); |
g_helper.Pointer()->enable_crash_key_logging(); |