AImage::close() can be called by AImageReader while holding
AImageReader::mLock.
Also fix ACaptureFailure double free issue.
Test: AR test app + CTS stress
Bug:
68885255
Change-Id: I17037e3e30e0f53b35ca538a3f321693c539cbdc
Merged-In: I17037e3e30e0f53b35ca538a3f321693c539cbdc
(cherry picked from commit
a10ab5bfd1ca27128fdbe43ce58a68e92b2896a1)
ACaptureRequest* request = allocateACaptureRequest(requestSp);
(*onFail)(context, session.get(), request, failure);
freeACaptureRequest(request);
- delete failure;
break;
}
case kWhatCaptureSeqEnd:
void
AImage::close(int releaseFenceFd) {
- lockReader();
Mutex::Autolock _l(mLock);
if (mIsClosed) {
return;
mBuffer = nullptr;
mLockedBuffer = nullptr;
mIsClosed = true;
- unlockReader();
}
void
void AImage_deleteAsync(AImage* image, int releaseFenceFd) {
ALOGV("%s", __FUNCTION__);
if (image != nullptr) {
+ image->lockReader();
image->close(releaseFenceFd);
+ image->unlockReader();
if (!image->isClosed()) {
LOG_ALWAYS_FATAL("Image close failed!");
}
for (auto it = mAcquiredImages.begin();
it != mAcquiredImages.end(); it++) {
AImage* image = *it;
+ Mutex::Autolock _l(image->mLock);
releaseImageLocked(image, /*releaseFenceFd*/-1);
- image->close();
}
// Delete Buffer Items
mBufferItemConsumer->releaseBuffer(*buffer, bufferFence);
returnBufferItemLocked(buffer);
image->mBuffer = nullptr;
+ image->mLockedBuffer = nullptr;
+ image->mIsClosed = true;
bool found = false;
// cleanup acquired image list
// Called by AImageReader_acquireXXX to acquire a Buffer and setup AImage.
media_status_t acquireImageLocked(/*out*/AImage** image, /*out*/int* fenceFd);
- // Called by AImage to close image
+ // Called by AImage/~AImageReader to close image. Caller is responsible to grab AImage::mLock
void releaseImageLocked(AImage* image, int releaseFenceFd);
static int getBufferWidth(BufferItem* buffer);