summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2009-09-29 11:12:57 -0700
committerEric Laurent <elaurent@google.com>2009-09-30 14:48:20 -0700
commitb7d94602e740e2fc9f98b573b5a3547189250599 (patch)
tree54aafea60d3f21fbf30b5507d75be9a15c51f327 /libs
parent486733c1fd564acd6d1b72e38147eb5e6d3a3d71 (diff)
downloadframeworks_base-b7d94602e740e2fc9f98b573b5a3547189250599.zip
frameworks_base-b7d94602e740e2fc9f98b573b5a3547189250599.tar.gz
frameworks_base-b7d94602e740e2fc9f98b573b5a3547189250599.tar.bz2
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')
-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 2ed5d3b..8e967fb 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;
}