Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: media/audio/audio_manager.cc

Issue 1806313003: Pass task runners to AudioManager constructor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: speculative hack to fix test timeouts Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/audio/audio_manager.h ('k') | media/audio/audio_manager_base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/audio_manager.h" 5 #include "media/audio/audio_manager.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/alias.h" 12 #include "base/debug/alias.h"
13 #include "base/debug/crash_logging.h" 13 #include "base/debug/crash_logging.h"
14 #include "base/debug/dump_without_crashing.h" 14 #include "base/debug/dump_without_crashing.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/metrics/histogram_macros.h" 19 #include "base/metrics/histogram_macros.h"
20 #include "base/power_monitor/power_monitor.h" 20 #include "base/power_monitor/power_monitor.h"
21 #include "base/run_loop.h"
21 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
22 #include "build/build_config.h" 23 #include "build/build_config.h"
23 #include "media/audio/audio_manager_factory.h" 24 #include "media/audio/audio_manager_factory.h"
24 #include "media/audio/fake_audio_log_factory.h" 25 #include "media/audio/fake_audio_log_factory.h"
25 #include "media/base/media_resources.h" 26 #include "media/base/media_resources.h"
26 #include "media/base/media_switches.h" 27 #include "media/base/media_switches.h"
27 28
28 #if defined(OS_WIN) 29 #if defined(OS_WIN)
29 #include "base/win/scoped_com_initializer.h" 30 #include "base/win/scoped_com_initializer.h"
30 #include "media/audio/win/core_audio_util_win.h" 31 #include "media/audio/win/core_audio_util_win.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 AudioManagerHelper() {} 70 AudioManagerHelper() {}
70 ~AudioManagerHelper() override {} 71 ~AudioManagerHelper() override {}
71 72
72 void HistogramThreadStatus(ThreadStatus status) { 73 void HistogramThreadStatus(ThreadStatus status) {
73 audio_thread_status_ = status; 74 audio_thread_status_ = status;
74 UMA_HISTOGRAM_ENUMERATION("Media.AudioThreadStatus", audio_thread_status_, 75 UMA_HISTOGRAM_ENUMERATION("Media.AudioThreadStatus", audio_thread_status_,
75 THREAD_MAX + 1); 76 THREAD_MAX + 1);
76 } 77 }
77 78
78 void StartHangTimer( 79 void StartHangTimer(
79 const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner) { 80 scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner) {
80 CHECK(!monitor_task_runner_); 81 CHECK(!monitor_task_runner_);
81 monitor_task_runner_ = monitor_task_runner; 82 monitor_task_runner_ = std::move(monitor_task_runner);
82 base::PowerMonitor::Get()->AddObserver(this); 83 base::PowerMonitor::Get()->AddObserver(this);
83 failed_pings_ = 0; 84 failed_pings_ = 0;
84 io_task_running_ = audio_task_running_ = true; 85 io_task_running_ = audio_task_running_ = true;
85 UpdateLastAudioThreadTimeTick(); 86 UpdateLastAudioThreadTimeTick();
86 RecordAudioThreadStatus(); 87 RecordAudioThreadStatus();
87 } 88 }
88 89
89 // Disable hang detection when the system goes into the suspend state. 90 // Disable hang detection when the system goes into the suspend state.
90 void OnSuspend() override { 91 void OnSuspend() override {
91 base::AutoLock lock(hang_lock_); 92 base::AutoLock lock(hang_lock_);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 #endif 249 #endif
249 250
250 DISALLOW_COPY_AND_ASSIGN(AudioManagerHelper); 251 DISALLOW_COPY_AND_ASSIGN(AudioManagerHelper);
251 }; 252 };
252 253
253 base::LazyInstance<AudioManagerHelper>::Leaky g_helper = 254 base::LazyInstance<AudioManagerHelper>::Leaky g_helper =
254 LAZY_INSTANCE_INITIALIZER; 255 LAZY_INSTANCE_INITIALIZER;
255 256
256 } // namespace 257 } // namespace
257 258
259 void AudioManagerDeleter::operator()(const AudioManager* instance) const {
260 CHECK(instance);
261 // We reset g_last_created here instead of in the destructor of AudioManager
262 // because the destructor runs on the audio thread. We want to always change
263 // g_last_created from the main thread.
264 if (g_last_created == instance) {
265 g_last_created = nullptr;
266 } else {
267 // We create multiple instances of AudioManager only when testing.
268 // We should not encounter this case in production.
269 LOG(WARNING) << "Multiple instances of AudioManager detected";
270 }
271
272 // AudioManager must be destroyed on the audio thread.
273 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
274 instance->GetTaskRunner();
275 if (task_runner->BelongsToCurrentThread()) {
276 delete instance;
277 // AudioManager destructor may post tasks to the message loop.
278 // Run those tasks to ensure that destruction is fully complete.
279 base::RunLoop().RunUntilIdle();
DaleCurtis 2016/04/06 22:07:49 I don't think this is allowed in production code.
alokp 2016/04/07 00:38:10 Done.
280 } else {
281 task_runner->DeleteSoon(FROM_HERE, instance);
DaleCurtis 2016/04/06 22:07:49 This can fail FYI, but should only do so if other
282 }
283 }
284
258 // Forward declaration of the platform specific AudioManager factory function. 285 // Forward declaration of the platform specific AudioManager factory function.
259 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory); 286 ScopedAudioManagerPtr CreateAudioManager(
287 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
288 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
289 AudioLogFactory* audio_log_factory);
260 290
261 AudioManager::AudioManager() {} 291 AudioManager::AudioManager(
292 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
293 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner)
294 : task_runner_(std::move(task_runner)),
295 worker_task_runner_(std::move(worker_task_runner)) {
296 DCHECK(task_runner_);
297 DCHECK(worker_task_runner_);
298
299 if (g_last_created) {
300 // We create multiple instances of AudioManager only when testing.
301 // We should not encounter this case in production.
302 LOG(WARNING) << "Multiple instances of AudioManager detected";
303 }
304 // We always override |g_last_created| irrespective of whether it is already
305 // set or not becuase it represents the last created instance.
306 g_last_created = this;
307 }
262 308
263 AudioManager::~AudioManager() { 309 AudioManager::~AudioManager() {
264 CHECK(!g_last_created || g_last_created == this); 310 DCHECK(task_runner_->BelongsToCurrentThread());
265 g_last_created = nullptr;
266 } 311 }
267 312
268 // static 313 // static
269 void AudioManager::SetFactory(AudioManagerFactory* factory) { 314 void AudioManager::SetFactory(AudioManagerFactory* factory) {
270 CHECK(factory); 315 CHECK(factory);
271 CHECK(!g_last_created); 316 CHECK(!g_last_created);
272 CHECK(!g_audio_manager_factory); 317 CHECK(!g_audio_manager_factory);
273 g_audio_manager_factory = factory; 318 g_audio_manager_factory = factory;
274 } 319 }
275 320
276 // static 321 // static
277 void AudioManager::ResetFactoryForTesting() { 322 void AudioManager::ResetFactoryForTesting() {
278 if (g_audio_manager_factory) { 323 if (g_audio_manager_factory) {
279 delete g_audio_manager_factory; 324 delete g_audio_manager_factory;
280 g_audio_manager_factory = nullptr; 325 g_audio_manager_factory = nullptr;
281 } 326 }
282 } 327 }
283 328
284 // static 329 // static
285 AudioManager* AudioManager::Create(AudioLogFactory* audio_log_factory) { 330 ScopedAudioManagerPtr AudioManager::Create(
286 CHECK(!g_last_created); 331 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
287 if (g_audio_manager_factory) 332 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
288 g_last_created = g_audio_manager_factory->CreateInstance(audio_log_factory); 333 scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner,
289 else 334 AudioLogFactory* audio_log_factory) {
290 g_last_created = CreateAudioManager(audio_log_factory); 335 DCHECK(task_runner);
336 DCHECK(worker_task_runner);
337 ScopedAudioManagerPtr manager;
338 if (g_audio_manager_factory) {
339 manager = g_audio_manager_factory->CreateInstance(
340 std::move(task_runner), std::move(worker_task_runner),
341 audio_log_factory);
342 } else {
343 manager =
344 CreateAudioManager(std::move(task_runner),
345 std::move(worker_task_runner), audio_log_factory);
346 }
291 347
292 return g_last_created; 348 if (monitor_task_runner)
293 } 349 g_helper.Pointer()->StartHangTimer(std::move(monitor_task_runner));
294
295 // static
296 AudioManager* AudioManager::CreateWithHangTimer(
297 AudioLogFactory* audio_log_factory,
298 const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner) {
299 AudioManager* manager = Create(audio_log_factory);
300
301 // On OSX the audio thread is the UI thread, for which a hang monitor is not
302 // necessary or recommended.
303 #if !defined(OS_MACOSX)
304 g_helper.Pointer()->StartHangTimer(monitor_task_runner);
305 #endif
306 350
307 return manager; 351 return manager;
308 } 352 }
309 353
310 // static 354 // static
311 AudioManager* AudioManager::CreateForTesting() { 355 ScopedAudioManagerPtr AudioManager::CreateForTesting(
356 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
312 #if defined(OS_WIN) 357 #if defined(OS_WIN)
313 g_helper.Pointer()->InitializeCOMForTesting(); 358 g_helper.Pointer()->InitializeCOMForTesting();
314 #endif 359 #endif
315 return Create(g_helper.Pointer()->fake_log_factory()); 360 return Create(task_runner, task_runner, nullptr,
361 g_helper.Pointer()->fake_log_factory());
316 } 362 }
317 363
318 // static 364 // static
319 void AudioManager::EnableCrashKeyLoggingForAudioThreadHangs() { 365 void AudioManager::EnableCrashKeyLoggingForAudioThreadHangs() {
320 CHECK(!g_last_created); 366 CHECK(!g_last_created);
321 g_helper.Pointer()->enable_crash_key_logging(); 367 g_helper.Pointer()->enable_crash_key_logging();
322 } 368 }
323 369
324 #if defined(OS_LINUX) 370 #if defined(OS_LINUX)
325 // static 371 // static
(...skipping 26 matching lines...) Expand all
352 std::string AudioManager::GetCommunicationsDeviceName() { 398 std::string AudioManager::GetCommunicationsDeviceName() {
353 #if defined(OS_WIN) 399 #if defined(OS_WIN)
354 return GetLocalizedStringUTF8(COMMUNICATIONS_AUDIO_DEVICE_NAME); 400 return GetLocalizedStringUTF8(COMMUNICATIONS_AUDIO_DEVICE_NAME);
355 #else 401 #else
356 NOTREACHED(); 402 NOTREACHED();
357 return ""; 403 return "";
358 #endif 404 #endif
359 } 405 }
360 406
361 } // namespace media 407 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_manager.h ('k') | media/audio/audio_manager_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698