summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2012-09-12 18:48:33 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2012-09-12 19:40:30 -0700
commit52762410dbc9189cd92a4094a1dbd4cfe8e71cb6 (patch)
tree8855f9e7af9e1e3aaec7e9f3c3550bf56425e8be /services/audioflinger
parent359cf1cac2a7851a59dfe4960a1a5992ac6fdb84 (diff)
downloadframeworks_av-52762410dbc9189cd92a4094a1dbd4cfe8e71cb6.zip
frameworks_av-52762410dbc9189cd92a4094a1dbd4cfe8e71cb6.tar.gz
frameworks_av-52762410dbc9189cd92a4094a1dbd4cfe8e71cb6.tar.bz2
Don't deadlock on AudioRecord start when reads return 0
When calling start() on an AudioRecord with a HAL that returns 0 on a read() operation, the start blocking condition was never unblocked. Add a boolean to track the first read operation so the returned number of bytes (mBytesRead) is only evaluated after that first read. Change-Id: I8c735a00d48cd6a0da467ccdf75d3616b38f6afa
Diffstat (limited to 'services/audioflinger')
-rw-r--r--services/audioflinger/AudioFlinger.cpp22
1 files changed, 14 insertions, 8 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 27e2ed2..a44fb3e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -5417,12 +5417,12 @@ void AudioFlinger::RecordThread::RecordTrack::stop()
/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
{
- result.append(" Clien Fmt Chn mask Session Buf S SRate Serv User\n");
+ result.append(" Clien Fmt Chn mask Session Buf S SRate Serv User FrameCount\n");
}
void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
{
- snprintf(buffer, size, " %05d %03u 0x%08x %05d %04u %01d %05u %08x %08x\n",
+ snprintf(buffer, size, " %05d %03u 0x%08x %05d %04u %01d %05u %08x %08x %05d\n",
(mClient == 0) ? getpid_cached : mClient->pid(),
mFormat,
mChannelMask,
@@ -5431,7 +5431,8 @@ void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
mState,
mCblk->sampleRate,
mCblk->server,
- mCblk->user);
+ mCblk->user,
+ mCblk->frameCount);
}
@@ -5983,6 +5984,9 @@ bool AudioFlinger::RecordThread::threadLoop()
inputStandBy();
acquireWakeLock();
+ // used to verify we've read at least one before evaluating how many bytes were read
+ bool readOnce = false;
+
// start recording
while (!exitPending()) {
@@ -6013,10 +6017,10 @@ bool AudioFlinger::RecordThread::threadLoop()
if (mReqChannelCount != mActiveTrack->channelCount()) {
mActiveTrack.clear();
mStartStopCond.broadcast();
- } else if (mBytesRead != 0) {
+ } else if (readOnce) {
// record start succeeds only if first read from audio input
// succeeds
- if (mBytesRead > 0) {
+ if (mBytesRead >= 0) {
mActiveTrack->mState = TrackBase::ACTIVE;
} else {
mActiveTrack.clear();
@@ -6045,6 +6049,7 @@ bool AudioFlinger::RecordThread::threadLoop()
buffer.frameCount = mFrameCount;
if (CC_LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
+ readOnce = true;
size_t framesOut = buffer.frameCount;
if (mResampler == NULL) {
// no resampling
@@ -6079,9 +6084,10 @@ bool AudioFlinger::RecordThread::threadLoop()
mBytesRead = mInput->stream->read(mInput->stream, mRsmpInBuffer, mInputBytes);
mRsmpInIndex = 0;
}
- if (mBytesRead < 0) {
- ALOGE("Error reading audio input");
- if (mActiveTrack->mState == TrackBase::ACTIVE) {
+ if (mBytesRead <= 0) {
+ if ((mBytesRead < 0) && (mActiveTrack->mState == TrackBase::ACTIVE))
+ {
+ ALOGE("Error reading audio input");
// Force input into standby so that it tries to
// recover at next read attempt
inputStandBy();