Add protection to few more methods of AudioDeviceLinuxALSA. Those methods can be called from

a different thread.

One example is the _playWarning can be changed in AudioDeviceLinuxALSA::Init, which is called on the application's thread. At the same time it can be read via PlayoutWarning() on the VoE's process_thread.

RISK=P2
TESTED=try bots and tsan test:
tools/valgrind-webrtc/webrtc_tests.sh --tool=tsan -t out/Debug/libjingle_peerconnection_unittest --gtest_filter=PeerConnectionFactoryTestInternal.CreatePCUsingInternalModules
BUG=1205
R=xians@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2315004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4866 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
wu@webrtc.org 2013-09-27 18:19:25 +00:00
parent 137b3793d9
commit 6049787252
2 changed files with 37 additions and 69 deletions

View File

@ -51,46 +51,6 @@
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# 2. libjingle stuff (talk folder) # 2. libjingle stuff (talk folder)
{
bug_1205_1
ThreadSanitizer:Race
fun:webrtc::AudioDeviceLinuxALSA::PlayoutWarning
fun:webrtc::AudioDeviceModuleImpl::Process
fun:webrtc::ProcessThreadImpl::Process
fun:webrtc::ProcessThreadImpl::Run
fun:webrtc::ThreadPosix::Run
fun:StartThread
}
{
bug_1205_2
ThreadSanitizer:Race
fun:webrtc::AudioDeviceLinuxALSA::PlayoutError
fun:webrtc::AudioDeviceModuleImpl::Process
fun:webrtc::ProcessThreadImpl::Process
fun:webrtc::ProcessThreadImpl::Run
fun:webrtc::ThreadPosix::Run
fun:StartThread
}
{
bug_1205_3
ThreadSanitizer:Race
fun:webrtc::AudioDeviceLinuxALSA::RecordingWarning
fun:webrtc::AudioDeviceModuleImpl::Process
fun:webrtc::ProcessThreadImpl::Process
fun:webrtc::ProcessThreadImpl::Run
fun:webrtc::ThreadPosix::Run
fun:StartThread
}
{
bug_1205_4
ThreadSanitizer:Race
fun:webrtc::AudioDeviceLinuxALSA::RecordingError
fun:webrtc::AudioDeviceModuleImpl::Process
fun:webrtc::ProcessThreadImpl::Process
fun:webrtc::ProcessThreadImpl::Run
fun:webrtc::ThreadPosix::Run
fun:StartThread
}
{ {
bug_1205_5 bug_1205_5
ThreadSanitizer:Race ThreadSanitizer:Race

View File

@ -122,7 +122,7 @@ AudioDeviceLinuxALSA::~AudioDeviceLinuxALSA()
{ {
WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id,
"%s destroyed", __FUNCTION__); "%s destroyed", __FUNCTION__);
Terminate(); Terminate();
// Clean up the recording buffer and playout buffer. // Clean up the recording buffer and playout buffer.
@ -415,7 +415,7 @@ int32_t AudioDeviceLinuxALSA::SpeakerVolume(uint32_t& volume) const
} }
volume = level; volume = level;
return 0; return 0;
} }
@ -451,7 +451,7 @@ int32_t AudioDeviceLinuxALSA::MaxSpeakerVolume(
} }
maxVolume = maxVol; maxVolume = maxVol;
return 0; return 0;
} }
@ -467,7 +467,7 @@ int32_t AudioDeviceLinuxALSA::MinSpeakerVolume(
} }
minVolume = minVol; minVolume = minVol;
return 0; return 0;
} }
@ -475,8 +475,8 @@ int32_t AudioDeviceLinuxALSA::SpeakerVolumeStepSize(
uint16_t& stepSize) const uint16_t& stepSize) const
{ {
uint16_t delta(0); uint16_t delta(0);
if (_mixerManager.SpeakerVolumeStepSize(delta) == -1) if (_mixerManager.SpeakerVolumeStepSize(delta) == -1)
{ {
return -1; return -1;
@ -527,15 +527,15 @@ int32_t AudioDeviceLinuxALSA::SetSpeakerMute(bool enable)
int32_t AudioDeviceLinuxALSA::SpeakerMute(bool& enabled) const int32_t AudioDeviceLinuxALSA::SpeakerMute(bool& enabled) const
{ {
bool muted(0); bool muted(0);
if (_mixerManager.SpeakerMute(muted) == -1) if (_mixerManager.SpeakerMute(muted) == -1)
{ {
return -1; return -1;
} }
enabled = muted; enabled = muted;
return 0; return 0;
} }
@ -584,8 +584,8 @@ int32_t AudioDeviceLinuxALSA::SetMicrophoneMute(bool enable)
int32_t AudioDeviceLinuxALSA::MicrophoneMute(bool& enabled) const int32_t AudioDeviceLinuxALSA::MicrophoneMute(bool& enabled) const
{ {
bool muted(0); bool muted(0);
if (_mixerManager.MicrophoneMute(muted) == -1) if (_mixerManager.MicrophoneMute(muted) == -1)
{ {
return -1; return -1;
@ -597,7 +597,7 @@ int32_t AudioDeviceLinuxALSA::MicrophoneMute(bool& enabled) const
int32_t AudioDeviceLinuxALSA::MicrophoneBoostIsAvailable(bool& available) int32_t AudioDeviceLinuxALSA::MicrophoneBoostIsAvailable(bool& available)
{ {
bool isAvailable(false); bool isAvailable(false);
bool wasInitialized = _mixerManager.MicrophoneIsInitialized(); bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
@ -635,15 +635,15 @@ int32_t AudioDeviceLinuxALSA::SetMicrophoneBoost(bool enable)
int32_t AudioDeviceLinuxALSA::MicrophoneBoost(bool& enabled) const int32_t AudioDeviceLinuxALSA::MicrophoneBoost(bool& enabled) const
{ {
bool onOff(0); bool onOff(0);
if (_mixerManager.MicrophoneBoost(onOff) == -1) if (_mixerManager.MicrophoneBoost(onOff) == -1)
{ {
return -1; return -1;
} }
enabled = onOff; enabled = onOff;
return 0; return 0;
} }
@ -665,7 +665,7 @@ int32_t AudioDeviceLinuxALSA::StereoRecordingIsAvailable(bool& available)
int recChannels = _recChannels; int recChannels = _recChannels;
available = false; available = false;
// Stop/uninitialize recording if initialized (and possibly started) // Stop/uninitialize recording if initialized (and possibly started)
if (_recIsInitialized) if (_recIsInitialized)
{ {
@ -736,7 +736,7 @@ int32_t AudioDeviceLinuxALSA::StereoPlayoutIsAvailable(bool& available)
int playChannels = _playChannels; int playChannels = _playChannels;
available = false; available = false;
// Stop/uninitialize recording if initialized (and possibly started) // Stop/uninitialize recording if initialized (and possibly started)
if (_playIsInitialized) if (_playIsInitialized)
{ {
@ -835,7 +835,7 @@ int32_t AudioDeviceLinuxALSA::SetMicrophoneVolume(uint32_t volume)
{ {
return (_mixerManager.SetMicrophoneVolume(volume)); return (_mixerManager.SetMicrophoneVolume(volume));
return 0; return 0;
} }
@ -852,7 +852,7 @@ int32_t AudioDeviceLinuxALSA::MicrophoneVolume(uint32_t& volume) const
} }
volume = level; volume = level;
return 0; return 0;
} }
@ -892,8 +892,8 @@ int32_t AudioDeviceLinuxALSA::MicrophoneVolumeStepSize(
uint16_t& stepSize) const uint16_t& stepSize) const
{ {
uint16_t delta(0); uint16_t delta(0);
if (_mixerManager.MicrophoneVolumeStepSize(delta) == -1) if (_mixerManager.MicrophoneVolumeStepSize(delta) == -1)
{ {
return -1; return -1;
@ -985,7 +985,7 @@ int32_t AudioDeviceLinuxALSA::RecordingDeviceName(
{ {
memset(guid, 0, kAdmMaxGuidSize); memset(guid, 0, kAdmMaxGuidSize);
} }
return GetDevicesInfo(1, false, index, name, kAdmMaxDeviceNameSize); return GetDevicesInfo(1, false, index, name, kAdmMaxDeviceNameSize);
} }
@ -1034,7 +1034,7 @@ int32_t AudioDeviceLinuxALSA::SetRecordingDevice(
int32_t AudioDeviceLinuxALSA::PlayoutIsAvailable(bool& available) int32_t AudioDeviceLinuxALSA::PlayoutIsAvailable(bool& available)
{ {
available = false; available = false;
// Try to initialize the playout side with mono // Try to initialize the playout side with mono
@ -1059,13 +1059,13 @@ int32_t AudioDeviceLinuxALSA::PlayoutIsAvailable(bool& available)
_playChannels = 2; _playChannels = 2;
} }
} }
return res; return res;
} }
int32_t AudioDeviceLinuxALSA::RecordingIsAvailable(bool& available) int32_t AudioDeviceLinuxALSA::RecordingIsAvailable(bool& available)
{ {
available = false; available = false;
// Try to initialize the recording side with mono // Try to initialize the recording side with mono
@ -1090,7 +1090,7 @@ int32_t AudioDeviceLinuxALSA::RecordingIsAvailable(bool& available)
_recChannels = 2; _recChannels = 2;
} }
} }
return res; return res;
} }
@ -1762,11 +1762,11 @@ int32_t AudioDeviceLinuxALSA::PlayoutBuffer(
type = _playBufType; type = _playBufType;
if (type == AudioDeviceModule::kFixedBufferSize) if (type == AudioDeviceModule::kFixedBufferSize)
{ {
sizeMS = _playBufDelayFixed; sizeMS = _playBufDelayFixed;
} }
else else
{ {
sizeMS = _playBufDelay; sizeMS = _playBufDelay;
} }
return 0; return 0;
@ -1782,41 +1782,49 @@ int32_t AudioDeviceLinuxALSA::CPULoad(uint16_t& load) const
bool AudioDeviceLinuxALSA::PlayoutWarning() const bool AudioDeviceLinuxALSA::PlayoutWarning() const
{ {
CriticalSectionScoped lock(&_critSect);
return (_playWarning > 0); return (_playWarning > 0);
} }
bool AudioDeviceLinuxALSA::PlayoutError() const bool AudioDeviceLinuxALSA::PlayoutError() const
{ {
CriticalSectionScoped lock(&_critSect);
return (_playError > 0); return (_playError > 0);
} }
bool AudioDeviceLinuxALSA::RecordingWarning() const bool AudioDeviceLinuxALSA::RecordingWarning() const
{ {
CriticalSectionScoped lock(&_critSect);
return (_recWarning > 0); return (_recWarning > 0);
} }
bool AudioDeviceLinuxALSA::RecordingError() const bool AudioDeviceLinuxALSA::RecordingError() const
{ {
CriticalSectionScoped lock(&_critSect);
return (_recError > 0); return (_recError > 0);
} }
void AudioDeviceLinuxALSA::ClearPlayoutWarning() void AudioDeviceLinuxALSA::ClearPlayoutWarning()
{ {
CriticalSectionScoped lock(&_critSect);
_playWarning = 0; _playWarning = 0;
} }
void AudioDeviceLinuxALSA::ClearPlayoutError() void AudioDeviceLinuxALSA::ClearPlayoutError()
{ {
CriticalSectionScoped lock(&_critSect);
_playError = 0; _playError = 0;
} }
void AudioDeviceLinuxALSA::ClearRecordingWarning() void AudioDeviceLinuxALSA::ClearRecordingWarning()
{ {
CriticalSectionScoped lock(&_critSect);
_recWarning = 0; _recWarning = 0;
} }
void AudioDeviceLinuxALSA::ClearRecordingError() void AudioDeviceLinuxALSA::ClearRecordingError()
{ {
CriticalSectionScoped lock(&_critSect);
_recError = 0; _recError = 0;
} }
@ -1831,7 +1839,7 @@ int32_t AudioDeviceLinuxALSA::GetDevicesInfo(
char* enumDeviceName, char* enumDeviceName,
const int32_t ednLen) const const int32_t ednLen) const
{ {
// Device enumeration based on libjingle implementation // Device enumeration based on libjingle implementation
// by Tristan Schmelcher at Google Inc. // by Tristan Schmelcher at Google Inc.