summaryrefslogtreecommitdiff
path: root/libs/audioflinger/AudioFlinger.cpp
diff options
context:
space:
mode:
author Eric Laurent <elaurent@google.com> 2009-09-29 11:12:57 -0700
committer Eric Laurent <elaurent@google.com> 2009-09-30 14:48:20 -0700
commit2d70c80a7f31ea9277c75af9666116e338482b09 (patch)
treeb21e44193f4ca006b4c34d4775e5ab5639b50339 /libs/audioflinger/AudioFlinger.cpp
parenta04f14a57a3d29e7f9d8b47e9594b5054115de70 (diff)
Fix issue 2153835: AudioFlinger: setParameters() can remain stuck if output thread is terminated.
Wait for the parameter set completed condition with a time out in ThreadBase::setParameters(). Also lock AudioFlinger mutex before accessing thread list in AudioFlinger::setParameters() and keep a strong reference on the thread being used in case it is exited while processing the request.
Diffstat (limited to 'libs/audioflinger/AudioFlinger.cpp')
-rw-r--r--libs/audioflinger/AudioFlinger.cpp37
1 files changed, 23 insertions, 14 deletions
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 2ed5d3b242..8e967fb5d2 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -603,18 +603,19 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
return result;
}
- // Check if parameters are for an output
- PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
- if (playbackThread != NULL) {
- return playbackThread->setParameters(keyValuePairs);
+ // hold a strong ref on thread in case closeOutput() or closeInput() is called
+ // and the thread is exited once the lock is released
+ sp<ThreadBase> thread;
+ {
+ Mutex::Autolock _l(mLock);
+ thread = checkPlaybackThread_l(ioHandle);
+ if (thread == NULL) {
+ thread = checkRecordThread_l(ioHandle);
+ }
}
-
- // Check if parameters are for an input
- RecordThread *recordThread = checkRecordThread_l(ioHandle);
- if (recordThread != NULL) {
- return recordThread->setParameters(keyValuePairs);
+ if (thread != NULL) {
+ return thread->setParameters(keyValuePairs);
}
-
return BAD_VALUE;
}
@@ -626,6 +627,9 @@ String8 AudioFlinger::getParameters(int ioHandle, const String8& keys)
if (ioHandle == 0) {
return mAudioHardware->getParameters(keys);
}
+
+ Mutex::Autolock _l(mLock);
+
PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
if (playbackThread != NULL) {
return playbackThread->getParameters(keys);
@@ -736,7 +740,7 @@ AudioFlinger::ThreadBase::~ThreadBase()
void AudioFlinger::ThreadBase::exit()
{
- // keep a strong ref on ourself so that we want get
+ // keep a strong ref on ourself so that we wont get
// destroyed in the middle of requestExitAndWait()
sp <ThreadBase> strongMe = this;
@@ -778,9 +782,14 @@ status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
mNewParameters.add(keyValuePairs);
mWaitWorkCV.signal();
- mParamCond.wait(mLock);
- status = mParamStatus;
- mWaitWorkCV.signal();
+ // wait condition with timeout in case the thread loop has exited
+ // before the request could be processed
+ if (mParamCond.waitRelative(mLock, seconds(2)) == NO_ERROR) {
+ status = mParamStatus;
+ mWaitWorkCV.signal();
+ } else {
+ status = TIMED_OUT;
+ }
return status;
}