Merge change Ibe2085be into eclair
* changes: Fix issue 2153835: AudioFlinger: setParameters() can remain stuck if output thread is terminated.
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user