Index: media/audio/audio_manager.cc |
diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc |
index 5d5f3b3a63337dd1df6fb307a6a17f046529704b..1ae75647190299c2879068baf26a184a85e3fc67 100644 |
--- a/media/audio/audio_manager.cc |
+++ b/media/audio/audio_manager.cc |
@@ -21,7 +21,6 @@ |
#include "base/strings/stringprintf.h" |
#include "build/build_config.h" |
#include "media/audio/audio_manager_factory.h" |
-#include "media/audio/fake_audio_log_factory.h" |
#include "media/base/media_resources.h" |
#include "media/base/media_switches.h" |
@@ -76,7 +75,7 @@ class AudioManagerHelper : public base::PowerObserver { |
} |
void StartHangTimer( |
- const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner) { |
+ scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner) { |
tommi (sloooow) - chröme
2016/03/19 02:32:41
does the caller use std::move?
alokp
2016/03/22 21:47:06
Done.
|
CHECK(!monitor_task_runner_); |
monitor_task_runner_ = monitor_task_runner; |
tommi (sloooow) - chröme
2016/03/19 02:32:41
if the above is intended, then you should use std:
alokp
2016/03/22 21:47:06
Done.
|
base::PowerMonitor::Get()->AddObserver(this); |
@@ -183,8 +182,6 @@ class AudioManagerHelper : public base::PowerObserver { |
max_hung_task_time_ / 5); |
} |
- AudioLogFactory* fake_log_factory() { return &fake_log_factory_; } |
- |
#if defined(OS_WIN) |
// This should be called before creating an AudioManager in tests to ensure |
// that the creating thread is COM initialized. |
@@ -224,8 +221,6 @@ class AudioManagerHelper : public base::PowerObserver { |
#endif |
} |
- FakeAudioLogFactory fake_log_factory_; |
- |
const base::TimeDelta max_hung_task_time_ = base::TimeDelta::FromMinutes(1); |
scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner_; |
@@ -255,14 +250,43 @@ base::LazyInstance<AudioManagerHelper>::Leaky g_helper = |
} // namespace |
-// Forward declaration of the platform specific AudioManager factory function. |
-AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory); |
+void AudioManagerDeleter::operator()(const AudioManager* instance) const { |
+ CHECK(instance); |
+ CHECK_EQ(g_last_created, 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; |
+ |
+ // AudioManager must be destroyed on the audio thread. |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
tommi (sloooow) - chröme
2016/03/19 02:32:41
won't we always be on the main thread when we get
alokp
2016/03/22 21:47:06
Are you suggesting always posting the task to dele
|
+ instance->GetTaskRunner(); |
+ if (task_runner->BelongsToCurrentThread()) { |
+ delete instance; |
+ } else { |
+ task_runner->DeleteSoon(FROM_HERE, instance); |
+ } |
+} |
-AudioManager::AudioManager() {} |
+// Forward declaration of the platform specific AudioManager factory function. |
+ScopedAudioManagerPtr CreateAudioManager( |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
+ AudioLogFactory* audio_log_factory); |
+ |
+AudioManager::AudioManager( |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner) |
+ : task_runner_(task_runner), worker_task_runner_(worker_task_runner) { |
+ DCHECK(task_runner_); |
+ DCHECK(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 |
@@ -282,40 +306,27 @@ 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); |
- else |
- g_last_created = CreateAudioManager(audio_log_factory); |
- |
- return g_last_created; |
-} |
+ScopedAudioManagerPtr AudioManager::Create( |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner, |
+ AudioLogFactory* audio_log_factory) { |
+ ScopedAudioManagerPtr manager; |
+ if (g_audio_manager_factory) { |
+ manager = g_audio_manager_factory->CreateInstance( |
+ task_runner, worker_task_runner, audio_log_factory); |
+ } else { |
+ manager = |
+ CreateAudioManager(task_runner, worker_task_runner, audio_log_factory); |
+ } |
-// static |
-AudioManager* AudioManager::CreateWithHangTimer( |
- AudioLogFactory* audio_log_factory, |
- const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner) { |
- AudioManager* manager = Create(audio_log_factory); |
- |
-// On OSX the audio thread is the UI thread, for which a hang monitor is not |
-// necessary or recommended. |
-#if !defined(OS_MACOSX) |
- g_helper.Pointer()->StartHangTimer(monitor_task_runner); |
-#endif |
+ if (monitor_task_runner) |
+ g_helper.Pointer()->StartHangTimer(monitor_task_runner); |
tommi (sloooow) - chröme
2016/03/19 02:32:41
std::move() (or see other comment)
alokp
2016/03/22 21:47:06
Done.
|
return manager; |
} |
// static |
-AudioManager* AudioManager::CreateForTesting() { |
-#if defined(OS_WIN) |
- g_helper.Pointer()->InitializeCOMForTesting(); |
-#endif |
- return Create(g_helper.Pointer()->fake_log_factory()); |
-} |
- |
-// static |
void AudioManager::EnableCrashKeyLoggingForAudioThreadHangs() { |
CHECK(!g_last_created); |
g_helper.Pointer()->enable_crash_key_logging(); |