Copy mActiveTrack for stability and easier access
Change-Id: If0d88610ec35128054a22f42b2d79f07c4b724eb
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 550b319..e3b8fe7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4200,7 +4200,6 @@
bool AudioFlinger::RecordThread::threadLoop()
{
AudioBufferProvider::Buffer buffer;
- sp<RecordTrack> activeTrack;
nsecs_t lastWarning = 0;
@@ -4212,6 +4211,7 @@
// start recording
for (;;) {
+ sp<RecordTrack> activeTrack;
Vector< sp<EffectChain> > effectChains;
{ // scope for mLock
@@ -4222,7 +4222,9 @@
processConfigEvents_l();
// return value 'reconfig' is currently unused
bool reconfig = checkForNewParameters_l();
- if (mActiveTrack == 0) {
+ // make a stable copy of mActiveTrack
+ activeTrack = mActiveTrack;
+ if (activeTrack == 0) {
standby();
// exitPending() can't become true here
releaseWakeLock_l();
@@ -4233,11 +4235,11 @@
acquireWakeLock_l();
continue;
}
- if (mActiveTrack->isTerminated()) {
- removeTrack_l(mActiveTrack);
+ if (activeTrack->isTerminated()) {
+ removeTrack_l(activeTrack);
mActiveTrack.clear();
} else {
- switch (mActiveTrack->mState) {
+ switch (activeTrack->mState) {
case TrackBase::PAUSING:
standby();
mActiveTrack.clear();
@@ -4245,14 +4247,14 @@
break;
case TrackBase::RESUMING:
- if (mReqChannelCount != mActiveTrack->channelCount()) {
+ if (mReqChannelCount != activeTrack->channelCount()) {
mActiveTrack.clear();
mStartStopCond.broadcast();
} else if (readOnce) {
// record start succeeds only if first read from audio input
// succeeds
if (mBytesRead >= 0) {
- mActiveTrack->mState = TrackBase::ACTIVE;
+ activeTrack->mState = TrackBase::ACTIVE;
} else {
mActiveTrack.clear();
}
@@ -4268,7 +4270,7 @@
break;
default:
- LOG_FATAL("Unexpected mActiveTrack->mState %d", mActiveTrack->mState);
+ LOG_FATAL("Unexpected activeTrack->mState %d", activeTrack->mState);
}
}
@@ -4278,11 +4280,10 @@
lockEffectChains_l(effectChains);
}
- // thread mutex is now unlocked and mActiveTrack != 0
- // FIXME RecordThread::start assigns to mActiveTrack under lock, but we read without lock
+ // thread mutex is now unlocked, mActiveTrack unknown, activeTrack != 0, kept, immutable
// FIXME RecordThread::stop assigns to mState under lock, but we read without lock
- if (mActiveTrack->mState != TrackBase::ACTIVE &&
- mActiveTrack->mState != TrackBase::RESUMING) {
+ if (activeTrack->mState != TrackBase::ACTIVE &&
+ activeTrack->mState != TrackBase::RESUMING) {
unlockEffectChains(effectChains);
usleep(kRecordThreadSleepUs);
continue;
@@ -4293,7 +4294,7 @@
}
buffer.frameCount = mFrameCount;
- status_t status = mActiveTrack->getNextBuffer(&buffer);
+ status_t status = activeTrack->getNextBuffer(&buffer);
if (status == NO_ERROR) {
readOnce = true;
size_t framesOut = buffer.frameCount;
@@ -4304,7 +4305,7 @@
if (framesIn > 0) {
int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) *
- mActiveTrack->mFrameSize;
+ activeTrack->mFrameSize;
if (framesIn > framesOut) {
framesIn = framesOut;
}
@@ -4335,7 +4336,7 @@
mBufferSize);
if (mBytesRead <= 0) {
// FIXME read mState without lock
- if ((mBytesRead < 0) && (mActiveTrack->mState == TrackBase::ACTIVE))
+ if ((mBytesRead < 0) && (activeTrack->mState == TrackBase::ACTIVE))
{
ALOGE("Error reading audio input");
// Force input into standby so that it tries to
@@ -4368,7 +4369,7 @@
mResampler->resample(mRsmpOutBuffer, framesOut,
this /* AudioBufferProvider* */);
// ditherAndClamp() works as long as all buffers returned by
- // mActiveTrack->getNextBuffer() are 32 bit aligned which should be always true.
+ // activeTrack->getNextBuffer() are 32 bit aligned which should be always true.
if (mChannelCount == 2 && mReqChannelCount == 1) {
// temporarily type pun mRsmpOutBuffer from Q19.12 to int16_t
ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut);
@@ -4383,7 +4384,7 @@
}
if (mFramestoDrop == 0) {
- mActiveTrack->releaseBuffer(&buffer);
+ activeTrack->releaseBuffer(&buffer);
} else {
if (mFramestoDrop > 0) {
mFramestoDrop -= buffer.frameCount;
@@ -4396,17 +4397,17 @@
mSyncStartEvent->isCancelled()) {
ALOGW("Synced record %s, session %d, trigger session %d",
(mFramestoDrop >= 0) ? "timed out" : "cancelled",
- mActiveTrack->sessionId(),
+ activeTrack->sessionId(),
(mSyncStartEvent != 0) ? mSyncStartEvent->triggerSession() : 0);
clearSyncStartEvent();
}
}
}
- mActiveTrack->clearOverflow();
+ activeTrack->clearOverflow();
}
// client isn't retrieving buffers fast enough
else {
- if (!mActiveTrack->setOverflow()) {
+ if (!activeTrack->setOverflow()) {
nsecs_t now = systemTime();
if ((now - lastWarning) > kWarningThrottleNs) {
ALOGW("RecordThread: buffer overflow");