Issue 4345021: Audio routed to multiple devices...
There is a possiblility that the condition on which RecordThread::checkForNewParameters_l()
waits after updating the command completion status is never signalled.
This happens if the thread executing ThreadBase::setParameters() has timed out waiting
for the status (for instance if the audio HAL takes too long to execute the setParameters()
command. Then the RecordThread is stuck forever.
The fix consists in waiting for the condition with a timeout in RecordThread::checkForNewParameters_l().
Change-Id: I7fc671bc2fc43ba4acb65a2beb33ee05742f091e
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 94efa74..a58f64c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -87,6 +87,8 @@
// RecordThread loop sleep time upon application overrun or audio HAL read error
static const int kRecordThreadSleepUs = 5000;
+static const nsecs_t kSetParametersTimeout = seconds(2);
+
// ----------------------------------------------------------------------------
static bool recordingAllowed() {
@@ -1032,7 +1034,7 @@
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) {
+ if (mParamCond.waitRelative(mLock, kSetParametersTimeout) == NO_ERROR) {
status = mParamStatus;
mWaitWorkCV.signal();
} else {
@@ -2349,7 +2351,9 @@
mParamStatus = status;
mParamCond.signal();
- mWaitWorkCV.wait(mLock);
+ // wait for condition with time out in case the thread calling ThreadBase::setParameters()
+ // already timed out waiting for the status and will never signal the condition.
+ mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout);
}
return reconfig;
}
@@ -2828,7 +2832,9 @@
mParamStatus = status;
mParamCond.signal();
- mWaitWorkCV.wait(mLock);
+ // wait for condition with time out in case the thread calling ThreadBase::setParameters()
+ // already timed out waiting for the status and will never signal the condition.
+ mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout);
}
return reconfig;
}
@@ -4669,7 +4675,9 @@
mParamStatus = status;
mParamCond.signal();
- mWaitWorkCV.wait(mLock);
+ // wait for condition with time out in case the thread calling ThreadBase::setParameters()
+ // already timed out waiting for the status and will never signal the condition.
+ mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout);
}
return reconfig;
}