Linux ADMs: fix recursive mutex locks.
This change fixes recursive locking going on in the Linux Pulse and ALSA audio device managers. Bug: webrtc:11866 Change-Id: Ia7b7b82e7f1f2a92c2f99e07a7079632499354ca Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/182020 Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Commit-Queue: Markus Handell <handellm@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31968}
This commit is contained in:
committed by
Commit Bot
parent
767ba0b384
commit
957318ceaf
@ -217,7 +217,10 @@ bool AudioDeviceLinuxALSA::Initialized() const {
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitSpeaker() {
|
||||
MutexLock lock(&mutex_);
|
||||
return InitSpeakerLocked();
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitSpeakerLocked() {
|
||||
if (_playing) {
|
||||
return -1;
|
||||
}
|
||||
@ -229,7 +232,10 @@ int32_t AudioDeviceLinuxALSA::InitSpeaker() {
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitMicrophone() {
|
||||
MutexLock lock(&mutex_);
|
||||
return InitMicrophoneLocked();
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitMicrophoneLocked() {
|
||||
if (_recording) {
|
||||
return -1;
|
||||
}
|
||||
@ -421,22 +427,22 @@ int32_t AudioDeviceLinuxALSA::StereoRecordingIsAvailable(bool& available) {
|
||||
|
||||
// Stop/uninitialize recording if initialized (and possibly started)
|
||||
if (_recIsInitialized) {
|
||||
StopRecording();
|
||||
StopRecordingLocked();
|
||||
}
|
||||
|
||||
// Try init in stereo;
|
||||
_recChannels = 2;
|
||||
if (InitRecording() == 0) {
|
||||
if (InitRecordingLocked() == 0) {
|
||||
available = true;
|
||||
}
|
||||
|
||||
// Stop/uninitialize recording
|
||||
StopRecording();
|
||||
StopRecordingLocked();
|
||||
|
||||
// Recover previous states
|
||||
_recChannels = recChannels;
|
||||
if (recIsInitialized) {
|
||||
InitRecording();
|
||||
InitRecordingLocked();
|
||||
}
|
||||
if (recording) {
|
||||
StartRecording();
|
||||
@ -481,22 +487,22 @@ int32_t AudioDeviceLinuxALSA::StereoPlayoutIsAvailable(bool& available) {
|
||||
|
||||
// Stop/uninitialize recording if initialized (and possibly started)
|
||||
if (_playIsInitialized) {
|
||||
StopPlayout();
|
||||
StopPlayoutLocked();
|
||||
}
|
||||
|
||||
// Try init in stereo;
|
||||
_playChannels = 2;
|
||||
if (InitPlayout() == 0) {
|
||||
if (InitPlayoutLocked() == 0) {
|
||||
available = true;
|
||||
}
|
||||
|
||||
// Stop/uninitialize recording
|
||||
StopPlayout();
|
||||
StopPlayoutLocked();
|
||||
|
||||
// Recover previous states
|
||||
_playChannels = playChannels;
|
||||
if (playIsInitialized) {
|
||||
InitPlayout();
|
||||
InitPlayoutLocked();
|
||||
}
|
||||
if (playing) {
|
||||
StartPlayout();
|
||||
@ -745,9 +751,13 @@ int32_t AudioDeviceLinuxALSA::RecordingIsAvailable(bool& available) {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitPlayout() {
|
||||
MutexLock lock(&mutex_);
|
||||
return InitPlayoutLocked();
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitPlayoutLocked() {
|
||||
int errVal = 0;
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
if (_playing) {
|
||||
return -1;
|
||||
}
|
||||
@ -760,7 +770,7 @@ int32_t AudioDeviceLinuxALSA::InitPlayout() {
|
||||
return 0;
|
||||
}
|
||||
// Initialize the speaker (devices might have been added or removed)
|
||||
if (InitSpeaker() == -1) {
|
||||
if (InitSpeakerLocked() == -1) {
|
||||
RTC_LOG(LS_WARNING) << "InitSpeaker() failed";
|
||||
}
|
||||
|
||||
@ -864,9 +874,12 @@ int32_t AudioDeviceLinuxALSA::InitPlayout() {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitRecording() {
|
||||
int errVal = 0;
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
return InitRecordingLocked();
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::InitRecordingLocked() {
|
||||
int errVal = 0;
|
||||
|
||||
if (_recording) {
|
||||
return -1;
|
||||
@ -881,7 +894,7 @@ int32_t AudioDeviceLinuxALSA::InitRecording() {
|
||||
}
|
||||
|
||||
// Initialize the microphone (devices might have been added or removed)
|
||||
if (InitMicrophone() == -1) {
|
||||
if (InitMicrophoneLocked() == -1) {
|
||||
RTC_LOG(LS_WARNING) << "InitMicrophone() failed";
|
||||
}
|
||||
|
||||
@ -1058,28 +1071,28 @@ int32_t AudioDeviceLinuxALSA::StartRecording() {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::StopRecording() {
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
return StopRecordingLocked();
|
||||
}
|
||||
|
||||
if (!_recIsInitialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_handleRecord == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure we don't start recording (it's asynchronous).
|
||||
_recIsInitialized = false;
|
||||
_recording = false;
|
||||
int32_t AudioDeviceLinuxALSA::StopRecordingLocked() {
|
||||
if (!_recIsInitialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_handleRecord == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure we don't start recording (it's asynchronous).
|
||||
_recIsInitialized = false;
|
||||
_recording = false;
|
||||
|
||||
if (_ptrThreadRec) {
|
||||
_ptrThreadRec->Stop();
|
||||
_ptrThreadRec.reset();
|
||||
}
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
_recordingFramesLeft = 0;
|
||||
if (_recordingBuffer) {
|
||||
delete[] _recordingBuffer;
|
||||
@ -1162,28 +1175,27 @@ int32_t AudioDeviceLinuxALSA::StartPlayout() {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceLinuxALSA::StopPlayout() {
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
return StopPlayoutLocked();
|
||||
}
|
||||
|
||||
if (!_playIsInitialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_handlePlayout == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_playing = false;
|
||||
int32_t AudioDeviceLinuxALSA::StopPlayoutLocked() {
|
||||
if (!_playIsInitialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_handlePlayout == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_playing = false;
|
||||
|
||||
// stop playout thread first
|
||||
if (_ptrThreadPlay) {
|
||||
_ptrThreadPlay->Stop();
|
||||
_ptrThreadPlay.reset();
|
||||
}
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
_playoutFramesLeft = 0;
|
||||
delete[] _playoutBuffer;
|
||||
_playoutBuffer = NULL;
|
||||
|
||||
@ -40,8 +40,8 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric {
|
||||
AudioDeviceModule::AudioLayer& audioLayer) const override;
|
||||
|
||||
// Main initializaton and termination
|
||||
InitStatus Init() override;
|
||||
int32_t Terminate() override;
|
||||
InitStatus Init() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Initialized() const override;
|
||||
|
||||
// Device enumeration
|
||||
@ -64,24 +64,24 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric {
|
||||
|
||||
// Audio transport initialization
|
||||
int32_t PlayoutIsAvailable(bool& available) override;
|
||||
int32_t InitPlayout() override;
|
||||
int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool PlayoutIsInitialized() const override;
|
||||
int32_t RecordingIsAvailable(bool& available) override;
|
||||
int32_t InitRecording() override;
|
||||
int32_t InitRecording() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool RecordingIsInitialized() const override;
|
||||
|
||||
// Audio transport control
|
||||
int32_t StartPlayout() override;
|
||||
int32_t StopPlayout() override;
|
||||
int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Playing() const override;
|
||||
int32_t StartRecording() override;
|
||||
int32_t StopRecording() override;
|
||||
int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Recording() const override;
|
||||
|
||||
// Audio mixer initialization
|
||||
int32_t InitSpeaker() override;
|
||||
int32_t InitSpeaker() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool SpeakerIsInitialized() const override;
|
||||
int32_t InitMicrophone() override;
|
||||
int32_t InitMicrophone() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool MicrophoneIsInitialized() const override;
|
||||
|
||||
// Speaker volume controls
|
||||
@ -109,19 +109,28 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric {
|
||||
int32_t MicrophoneMute(bool& enabled) const override;
|
||||
|
||||
// Stereo support
|
||||
int32_t StereoPlayoutIsAvailable(bool& available) override;
|
||||
int32_t StereoPlayoutIsAvailable(bool& available)
|
||||
RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t SetStereoPlayout(bool enable) override;
|
||||
int32_t StereoPlayout(bool& enabled) const override;
|
||||
int32_t StereoRecordingIsAvailable(bool& available) override;
|
||||
int32_t StereoRecordingIsAvailable(bool& available)
|
||||
RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t SetStereoRecording(bool enable) override;
|
||||
int32_t StereoRecording(bool& enabled) const override;
|
||||
|
||||
// Delay information and control
|
||||
int32_t PlayoutDelay(uint16_t& delayMS) const override;
|
||||
|
||||
void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
|
||||
void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer)
|
||||
RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
|
||||
private:
|
||||
int32_t InitRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t StopRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t StopPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t InitPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t InitSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t InitMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t GetDevicesInfo(const int32_t function,
|
||||
const bool playback,
|
||||
const int32_t enumDeviceNo = 0,
|
||||
|
||||
@ -116,7 +116,7 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric {
|
||||
|
||||
// Main initializaton and termination
|
||||
InitStatus Init() override;
|
||||
int32_t Terminate() override;
|
||||
int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Initialized() const override;
|
||||
|
||||
// Device enumeration
|
||||
@ -139,18 +139,18 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric {
|
||||
|
||||
// Audio transport initialization
|
||||
int32_t PlayoutIsAvailable(bool& available) override;
|
||||
int32_t InitPlayout() override;
|
||||
int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool PlayoutIsInitialized() const override;
|
||||
int32_t RecordingIsAvailable(bool& available) override;
|
||||
int32_t InitRecording() override;
|
||||
bool RecordingIsInitialized() const override;
|
||||
|
||||
// Audio transport control
|
||||
int32_t StartPlayout() override;
|
||||
int32_t StopPlayout() override;
|
||||
int32_t StartPlayout() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Playing() const override;
|
||||
int32_t StartRecording() override;
|
||||
int32_t StopRecording() override;
|
||||
int32_t StartRecording() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Recording() const override;
|
||||
|
||||
// Audio mixer initialization
|
||||
@ -192,7 +192,8 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric {
|
||||
int32_t StereoRecording(bool& enabled) const override;
|
||||
|
||||
// Delay information and control
|
||||
int32_t PlayoutDelay(uint16_t& delayMS) const override;
|
||||
int32_t PlayoutDelay(uint16_t& delayMS) const
|
||||
RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
|
||||
void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
|
||||
|
||||
@ -256,8 +257,8 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric {
|
||||
|
||||
static void RecThreadFunc(void*);
|
||||
static void PlayThreadFunc(void*);
|
||||
bool RecThreadProcess();
|
||||
bool PlayThreadProcess();
|
||||
bool RecThreadProcess() RTC_LOCKS_EXCLUDED(mutex_);
|
||||
bool PlayThreadProcess() RTC_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
AudioDeviceBuffer* _ptrAudioBuffer;
|
||||
|
||||
|
||||
@ -47,16 +47,19 @@ int32_t AudioMixerManagerLinuxALSA::Close() {
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
CloseSpeaker();
|
||||
CloseMicrophone();
|
||||
CloseSpeakerLocked();
|
||||
CloseMicrophoneLocked();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() {
|
||||
RTC_LOG(LS_VERBOSE) << __FUNCTION__;
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
return CloseSpeakerLocked();
|
||||
}
|
||||
|
||||
int32_t AudioMixerManagerLinuxALSA::CloseSpeakerLocked() {
|
||||
RTC_LOG(LS_VERBOSE) << __FUNCTION__;
|
||||
|
||||
int errVal = 0;
|
||||
|
||||
@ -86,9 +89,12 @@ int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() {
|
||||
}
|
||||
|
||||
int32_t AudioMixerManagerLinuxALSA::CloseMicrophone() {
|
||||
RTC_LOG(LS_VERBOSE) << __FUNCTION__;
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
return CloseMicrophoneLocked();
|
||||
}
|
||||
|
||||
int32_t AudioMixerManagerLinuxALSA::CloseMicrophoneLocked() {
|
||||
RTC_LOG(LS_VERBOSE) << __FUNCTION__;
|
||||
|
||||
int errVal = 0;
|
||||
|
||||
|
||||
@ -21,27 +21,27 @@ namespace webrtc {
|
||||
|
||||
class AudioMixerManagerLinuxALSA {
|
||||
public:
|
||||
int32_t OpenSpeaker(char* deviceName);
|
||||
int32_t OpenMicrophone(char* deviceName);
|
||||
int32_t SetSpeakerVolume(uint32_t volume);
|
||||
int32_t OpenSpeaker(char* deviceName) RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t OpenMicrophone(char* deviceName) RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t SetSpeakerVolume(uint32_t volume) RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t SpeakerVolume(uint32_t& volume) const;
|
||||
int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
|
||||
int32_t MinSpeakerVolume(uint32_t& minVolume) const;
|
||||
int32_t SpeakerVolumeIsAvailable(bool& available);
|
||||
int32_t SpeakerMuteIsAvailable(bool& available);
|
||||
int32_t SetSpeakerMute(bool enable);
|
||||
int32_t SetSpeakerMute(bool enable) RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t SpeakerMute(bool& enabled) const;
|
||||
int32_t MicrophoneMuteIsAvailable(bool& available);
|
||||
int32_t SetMicrophoneMute(bool enable);
|
||||
int32_t SetMicrophoneMute(bool enable) RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t MicrophoneMute(bool& enabled) const;
|
||||
int32_t MicrophoneVolumeIsAvailable(bool& available);
|
||||
int32_t SetMicrophoneVolume(uint32_t volume);
|
||||
int32_t SetMicrophoneVolume(uint32_t volume) RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t MicrophoneVolume(uint32_t& volume) const;
|
||||
int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
|
||||
int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
|
||||
int32_t Close();
|
||||
int32_t CloseSpeaker();
|
||||
int32_t CloseMicrophone();
|
||||
int32_t Close() RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t CloseSpeaker() RTC_LOCKS_EXCLUDED(mutex_);
|
||||
int32_t CloseMicrophone() RTC_LOCKS_EXCLUDED(mutex_);
|
||||
bool SpeakerIsInitialized() const;
|
||||
bool MicrophoneIsInitialized() const;
|
||||
|
||||
@ -50,6 +50,8 @@ class AudioMixerManagerLinuxALSA {
|
||||
~AudioMixerManagerLinuxALSA();
|
||||
|
||||
private:
|
||||
int32_t CloseSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t CloseMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
int32_t LoadMicMixerElement() const;
|
||||
int32_t LoadSpeakerMixerElement() const;
|
||||
void GetControlName(char* controlName, char* deviceName) const;
|
||||
|
||||
Reference in New Issue
Block a user