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

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

Issue 2784433002: Ensures that audio tasks cannot run after AudioManager is deleted. (Closed)
Patch Set: cleanup Created 3 years, 7 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
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_base.h" 5 #include "media/audio/audio_manager_base.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 // dispatcher are the same as the request dispatcher. 76 // dispatcher are the same as the request dispatcher.
77 return (dispatcher_->input_params.Equals(dispatcher_in->input_params) && 77 return (dispatcher_->input_params.Equals(dispatcher_in->input_params) &&
78 dispatcher_->output_params.Equals(dispatcher_in->output_params) && 78 dispatcher_->output_params.Equals(dispatcher_in->output_params) &&
79 dispatcher_->output_device_id == dispatcher_in->output_device_id); 79 dispatcher_->output_device_id == dispatcher_in->output_device_id);
80 } 80 }
81 81
82 private: 82 private:
83 const DispatcherParams* dispatcher_; 83 const DispatcherParams* dispatcher_;
84 }; 84 };
85 85
86 AudioManagerBase::AudioManagerBase( 86 AudioManagerBase::AudioManagerBase(std::unique_ptr<AudioThread> audio_thread,
87 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 87 AudioLogFactory* audio_log_factory)
88 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, 88 : AudioManager(std::move(audio_thread)),
89 AudioLogFactory* audio_log_factory)
90 : AudioManager(std::move(task_runner), std::move(worker_task_runner)),
91 max_num_output_streams_(kDefaultMaxOutputStreams), 89 max_num_output_streams_(kDefaultMaxOutputStreams),
92 max_num_input_streams_(kDefaultMaxInputStreams), 90 max_num_input_streams_(kDefaultMaxInputStreams),
93 num_output_streams_(0), 91 num_output_streams_(0),
94 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we 92 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we
95 // don't block the UI thread when swapping devices. 93 // don't block the UI thread when swapping devices.
96 output_listeners_( 94 output_listeners_(
97 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), 95 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY),
98 audio_log_factory_(audio_log_factory) {} 96 audio_log_factory_(audio_log_factory) {}
99 97
100 AudioManagerBase::~AudioManagerBase() { 98 AudioManagerBase::~AudioManagerBase() {
101 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
102
103 // All the output streams should have been deleted. 99 // All the output streams should have been deleted.
104 CHECK_EQ(0, num_output_streams_); 100 CHECK_EQ(0, num_output_streams_);
105 // All the input streams should have been deleted. 101 // All the input streams should have been deleted.
106 CHECK(input_streams_.empty()); 102 CHECK(input_streams_.empty());
107 } 103 }
108 104
109 base::string16 AudioManagerBase::GetAudioInputDeviceModel() { 105 base::string16 AudioManagerBase::GetAudioInputDeviceModel() {
110 return base::string16(); 106 return base::string16();
111 } 107 }
112 108
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 if (it != output_dispatchers_.end()) { 282 if (it != output_dispatchers_.end()) {
287 delete dispatcher_params; 283 delete dispatcher_params;
288 return (*it)->dispatcher->CreateStreamProxy(); 284 return (*it)->dispatcher->CreateStreamProxy();
289 } 285 }
290 286
291 const base::TimeDelta kCloseDelay = 287 const base::TimeDelta kCloseDelay =
292 base::TimeDelta::FromSeconds(kStreamCloseDelaySeconds); 288 base::TimeDelta::FromSeconds(kStreamCloseDelaySeconds);
293 std::unique_ptr<AudioOutputDispatcher> dispatcher; 289 std::unique_ptr<AudioOutputDispatcher> dispatcher;
294 if (output_params.format() != AudioParameters::AUDIO_FAKE) { 290 if (output_params.format() != AudioParameters::AUDIO_FAKE) {
295 // Using unretained for |debug_recording_manager_| is safe since it 291 // Using unretained for |debug_recording_manager_| is safe since it
296 // outlives the dispatchers (cleared in Shutdown()). 292 // outlives the dispatchers (cleared in ShutdownOnAudioThread()).
297 dispatcher = base::MakeUnique<AudioOutputResampler>( 293 dispatcher = base::MakeUnique<AudioOutputResampler>(
298 this, params, output_params, output_device_id, kCloseDelay, 294 this, params, output_params, output_device_id, kCloseDelay,
299 debug_recording_manager_ 295 debug_recording_manager_
300 ? base::BindRepeating( 296 ? base::BindRepeating(
301 &AudioDebugRecordingManager::RegisterDebugRecordingSource, 297 &AudioDebugRecordingManager::RegisterDebugRecordingSource,
302 base::Unretained(debug_recording_manager_.get()), 298 base::Unretained(debug_recording_manager_.get()),
303 FILE_PATH_LITERAL("output")) 299 FILE_PATH_LITERAL("output"))
304 : base::BindRepeating(&GetNullptrAudioDebugRecorder)); 300 : base::BindRepeating(&GetNullptrAudioDebugRecorder));
305 } else { 301 } else {
306 dispatcher = base::MakeUnique<AudioOutputDispatcherImpl>( 302 dispatcher = base::MakeUnique<AudioOutputDispatcherImpl>(
(...skipping 28 matching lines...) Expand all
335 } 331 }
336 332
337 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { 333 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) {
338 CHECK(GetTaskRunner()->BelongsToCurrentThread()); 334 CHECK(GetTaskRunner()->BelongsToCurrentThread());
339 DCHECK(stream); 335 DCHECK(stream);
340 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. 336 // TODO(xians) : Have a clearer destruction path for the AudioInputStream.
341 CHECK_EQ(1u, input_streams_.erase(stream)); 337 CHECK_EQ(1u, input_streams_.erase(stream));
342 delete stream; 338 delete stream;
343 } 339 }
344 340
345 void AudioManagerBase::Shutdown() { 341 void AudioManagerBase::ShutdownOnAudioThread() {
346 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 342 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
347 343
348 // Close all output streams. 344 // Close all output streams.
349 output_dispatchers_.clear(); 345 output_dispatchers_.clear();
350 346
351 #if defined(OS_MACOSX) 347 #if defined(OS_MACOSX)
352 // On mac, AudioManager runs on the main thread, loop for which stops 348 // On mac, AudioManager runs on the main thread, loop for which stops
353 // processing task queue at this point. So even if tasks to close the 349 // processing task queue at this point. So even if tasks to close the
354 // streams are enqueued, they would not run leading to CHECKs getting hit 350 // streams are enqueued, they would not run leading to CHECKs getting hit
355 // in the destructor about open streams. Close them explicitly here. 351 // in the destructor about open streams. Close them explicitly here.
356 // crbug.com/608049. 352 // crbug.com/608049.
357 for (auto iter = input_streams_.begin(); iter != input_streams_.end();) { 353 for (auto iter = input_streams_.begin(); iter != input_streams_.end();) {
358 // Note: Closing the stream will invalidate the iterator. 354 // Note: Closing the stream will invalidate the iterator.
359 // Increment the iterator before closing the stream. 355 // Increment the iterator before closing the stream.
360 AudioInputStream* stream = *iter++; 356 AudioInputStream* stream = *iter++;
361 stream->Close(); 357 stream->Close();
362 } 358 }
363 CHECK(input_streams_.empty());
364 #endif // OS_MACOSX 359 #endif // OS_MACOSX
365 } 360 }
366 361
367 void AudioManagerBase::AddOutputDeviceChangeListener( 362 void AudioManagerBase::AddOutputDeviceChangeListener(
368 AudioDeviceListener* listener) { 363 AudioDeviceListener* listener) {
369 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 364 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
370 output_listeners_.AddObserver(listener); 365 output_listeners_.AddObserver(listener);
371 } 366 }
372 367
373 void AudioManagerBase::RemoveOutputDeviceChangeListener( 368 void AudioManagerBase::RemoveOutputDeviceChangeListener(
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 std::move(task_runner), std::move(file_task_runner)); 482 std::move(task_runner), std::move(file_task_runner));
488 } 483 }
489 484
490 void AudioManagerBase::SetMaxStreamCountForTesting(int max_input, 485 void AudioManagerBase::SetMaxStreamCountForTesting(int max_input,
491 int max_output) { 486 int max_output) {
492 max_num_output_streams_ = max_output; 487 max_num_output_streams_ = max_output;
493 max_num_input_streams_ = max_input; 488 max_num_input_streams_ = max_input;
494 } 489 }
495 490
496 } // namespace media 491 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698