am 7e1af37c: Merge change Ibe2085be into eclair

Merge commit '7e1af37c3148112d9c801272bfa6359a005baf6d' into eclair-plus-aosp

* commit '7e1af37c3148112d9c801272bfa6359a005baf6d':
  Fix issue 2153835: AudioFlinger: setParameters() can remain stuck if output thread is terminated.
This commit is contained in:
Eric Laurent
2009-09-30 21:12:11 -07:00
committed by Android Git Automerger

View File

@@ -603,18 +603,19 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
return result; return result;
} }
// Check if parameters are for an output // hold a strong ref on thread in case closeOutput() or closeInput() is called
PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle); // and the thread is exited once the lock is released
if (playbackThread != NULL) { sp<ThreadBase> thread;
return playbackThread->setParameters(keyValuePairs); {
Mutex::Autolock _l(mLock);
thread = checkPlaybackThread_l(ioHandle);
if (thread == NULL) {
thread = checkRecordThread_l(ioHandle);
}
} }
if (thread != NULL) {
// Check if parameters are for an input return thread->setParameters(keyValuePairs);
RecordThread *recordThread = checkRecordThread_l(ioHandle);
if (recordThread != NULL) {
return recordThread->setParameters(keyValuePairs);
} }
return BAD_VALUE; return BAD_VALUE;
} }
@@ -626,6 +627,9 @@ String8 AudioFlinger::getParameters(int ioHandle, const String8& keys)
if (ioHandle == 0) { if (ioHandle == 0) {
return mAudioHardware->getParameters(keys); return mAudioHardware->getParameters(keys);
} }
Mutex::Autolock _l(mLock);
PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle); PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
if (playbackThread != NULL) { if (playbackThread != NULL) {
return playbackThread->getParameters(keys); return playbackThread->getParameters(keys);
@@ -736,7 +740,7 @@ AudioFlinger::ThreadBase::~ThreadBase()
void AudioFlinger::ThreadBase::exit() 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() // destroyed in the middle of requestExitAndWait()
sp <ThreadBase> strongMe = this; sp <ThreadBase> strongMe = this;
@@ -778,9 +782,14 @@ status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
mNewParameters.add(keyValuePairs); mNewParameters.add(keyValuePairs);
mWaitWorkCV.signal(); mWaitWorkCV.signal();
mParamCond.wait(mLock); // wait condition with timeout in case the thread loop has exited
status = mParamStatus; // before the request could be processed
mWaitWorkCV.signal(); if (mParamCond.waitRelative(mLock, seconds(2)) == NO_ERROR) {
status = mParamStatus;
mWaitWorkCV.signal();
} else {
status = TIMED_OUT;
}
return status; return status;
} }