Commit 9055ba2b authored by henrika@chromium.org's avatar henrika@chromium.org

Avoids crash in PCMWaveInAudioInputStream::WaveCallback

BUG=12092064
TEST=
Review URL: https://codereview.chromium.org/12092064

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@180125 0039d316-1c4b-4281-b951-d872f2087c98
parent 9986e3cd
...@@ -152,6 +152,7 @@ void PCMWaveInAudioInputStream::Stop() { ...@@ -152,6 +152,7 @@ void PCMWaveInAudioInputStream::Stop() {
HandleError(::GetLastError()); HandleError(::GetLastError());
return; return;
} }
// Stop is always called before Close. In case of error, this will be // Stop is always called before Close. In case of error, this will be
// also called when closing the input controller. // also called when closing the input controller.
manager_->DecreaseActiveInputStreamCount(); manager_->DecreaseActiveInputStreamCount();
...@@ -163,6 +164,13 @@ void PCMWaveInAudioInputStream::Stop() { ...@@ -163,6 +164,13 @@ void PCMWaveInAudioInputStream::Stop() {
HandleError(res); HandleError(res);
return; return;
} }
// Wait for lock to ensure all outstanding callbacks have completed.
base::AutoLock auto_lock(lock_);
// Don't use callback after Stop().
callback_ = NULL;
state_ = kStateReady; state_ = kStateReady;
} }
...@@ -265,6 +273,9 @@ void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg, ...@@ -265,6 +273,9 @@ void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg,
PCMWaveInAudioInputStream* obj = PCMWaveInAudioInputStream* obj =
reinterpret_cast<PCMWaveInAudioInputStream*>(instance); reinterpret_cast<PCMWaveInAudioInputStream*>(instance);
// The lock ensures that Stop() can't be called during a callback.
base::AutoLock auto_lock(obj->lock_);
if (msg == WIM_DATA) { if (msg == WIM_DATA) {
// WIM_DONE indicates that the driver is done with our buffer. We pass it // WIM_DONE indicates that the driver is done with our buffer. We pass it
// to the callback and check if we need to stop playing. // to the callback and check if we need to stop playing.
...@@ -273,10 +284,13 @@ void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg, ...@@ -273,10 +284,13 @@ void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg,
// TODO(henrika): the |volume| parameter is always set to zero since there // TODO(henrika): the |volume| parameter is always set to zero since there
// is currently no support for controlling the microphone volume level. // is currently no support for controlling the microphone volume level.
WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1); WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1);
obj->callback_->OnData(obj, reinterpret_cast<const uint8*>(buffer->lpData), if (obj->callback_) {
buffer->dwBytesRecorded, obj->callback_->OnData(obj,
buffer->dwBytesRecorded, reinterpret_cast<const uint8*>(buffer->lpData),
0.0); buffer->dwBytesRecorded,
buffer->dwBytesRecorded,
0.0);
}
if (obj->state_ == kStateStopping) { if (obj->state_ == kStateStopping) {
// The main thread has called Stop() and is waiting to issue waveOutReset // The main thread has called Stop() and is waiting to issue waveOutReset
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/synchronization/lock.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
#include "media/audio/audio_io.h" #include "media/audio/audio_io.h"
#include "media/audio/audio_parameters.h" #include "media/audio/audio_parameters.h"
...@@ -116,6 +117,9 @@ class PCMWaveInAudioInputStream : public AudioInputStream { ...@@ -116,6 +117,9 @@ class PCMWaveInAudioInputStream : public AudioInputStream {
// An event that is signaled when the callback thread is ready to stop. // An event that is signaled when the callback thread is ready to stop.
base::win::ScopedHandle stopped_event_; base::win::ScopedHandle stopped_event_;
// Lock used to avoid conflicts when Stop() is called during a callback.
base::Lock lock_;
DISALLOW_COPY_AND_ASSIGN(PCMWaveInAudioInputStream); DISALLOW_COPY_AND_ASSIGN(PCMWaveInAudioInputStream);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment