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

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

Powered by Google App Engine
This is Rietveld 408576698