summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChrister Fletcher <christer.fletcher@sonymobile.com>2013-01-18 15:27:03 +0100
committerHenrik Baard <henrik.baard@sonymobile.com>2013-06-20 13:36:58 +0200
commit5fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0 (patch)
treee3ca90035d580a1cfe7d786b45a9d31a49da1f76
parent132bc5bd1c68aa807a20e1655f009f74433be588 (diff)
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
-rw-r--r--services/audioflinger/AudioPolicyService.cpp14
1 files changed, 8 insertions, 6 deletions
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 8b99bd27..55e08269 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;
}