From 5fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0 Mon Sep 17 00:00:00 2001 From: Christer Fletcher Date: Fri, 18 Jan 2013 15:27:03 +0100 Subject: Prevent AudioCommands being freed before read When AudioCommandThread::threadLoop process AudioCommands it was possible for it to delete a command where the posting thread still hadn't read that status from it. If a second command signaled the thread loop to continue after it had inserted a new command while the thread loop was actually waiting for the first command to report that it had read the status the thread loop would continue and delete the first command. Changed the wait condition when waiting for the calling thread to read status to use command->mCond instead of mWaitWorkCV. This way it's guaranteed that the signal to continue comes from the correct thread. Change-Id: Ia69b48cb4fdfaf8b4c83b56a197fb9f2058a92d1 --- services/audioflinger/AudioPolicyService.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'services') diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 8b99bd2..55e0826 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -49,6 +49,8 @@ static const char kCmdDeadlockedString[] = "AudioPolicyService command thread ma static const int kDumpLockRetries = 50; static const int kDumpLockSleepUs = 20000; +static const nsecs_t kAudioCommandTimeout = 3000000000; // 3 seconds + namespace { extern struct audio_policy_service_ops aps_ops; }; @@ -697,7 +699,7 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() data->mIO); if (command->mWaitStatus) { command->mCond.signal(); - mWaitWorkCV.wait(mLock); + command->mCond.waitRelative(mLock, kAudioCommandTimeout); } delete data; }break; @@ -708,7 +710,7 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs); if (command->mWaitStatus) { command->mCond.signal(); - mWaitWorkCV.wait(mLock); + command->mCond.waitRelative(mLock, kAudioCommandTimeout); } delete data; }break; @@ -719,7 +721,7 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); if (command->mWaitStatus) { command->mCond.signal(); - mWaitWorkCV.wait(mLock); + command->mCond.waitRelative(mLock, kAudioCommandTimeout); } delete data; }break; @@ -827,7 +829,7 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type if (command->mWaitStatus) { command->mCond.wait(mLock); status = command->mStatus; - mWaitWorkCV.signal(); + command->mCond.signal(); } return status; } @@ -852,7 +854,7 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_hand if (command->mWaitStatus) { command->mCond.wait(mLock); status = command->mStatus; - mWaitWorkCV.signal(); + command->mCond.signal(); } return status; } @@ -873,7 +875,7 @@ status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume if (command->mWaitStatus) { command->mCond.wait(mLock); status = command->mStatus; - mWaitWorkCV.signal(); + command->mCond.signal(); } return status; } -- cgit v1.1