diff options
| author | Emilian Peev <epeev@google.com> | 2017-06-26 14:28:31 -0700 |
|---|---|---|
| committer | Emilian Peev <epeev@google.com> | 2017-06-30 00:41:09 +0000 |
| commit | e06ed957c8c83bfa96fafa1e4a0355adaf14718b (patch) | |
| tree | 1c5e4f360c8c2a5169be45cea9b512e5c7b09f1d /camera | |
| parent | 54c6fafa92ebddec1c6d5e9da4e360b22578f661 (diff) | |
QCamera3: Avoid possible deadlock when reporting failed buffers
"QCamera3YUVChannel::streamCbRoutine" will acquire "mOfflinePpLock"
before calling the channel error callback. The current callback
implementation will also try to acquire "mMutex". This could trigger
a deadlock in case a request for the YUV channel is also currently
executing. The request will acquire "mMutex" first and then try
to lock "mOfflinePpLock".
Bug: 63002361
Test: Complete Camera/Camera2 CTS.
Change-Id: I2877aebf94c5a15b6742548bcbd1d1c4adc5e9d2
Diffstat (limited to 'camera')
| -rw-r--r-- | camera/QCamera2/HAL3/QCamera3Channel.cpp | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp index e14442e7..8bd1deb4 100644 --- a/camera/QCamera2/HAL3/QCamera3Channel.cpp +++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp @@ -2839,56 +2839,62 @@ void QCamera3YUVChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, } if (mBypass) { - List<PpInfo>::iterator ppInfo; - - Mutex::Autolock lock(mOfflinePpLock); - resultFrameNumber = mMemory.getFrameNumber(frameIndex); - for (ppInfo = mOfflinePpInfoList.begin(); - ppInfo != mOfflinePpInfoList.end(); ppInfo++) { - if (ppInfo->frameNumber == (uint32_t)resultFrameNumber) { - break; - } - } - LOGD("frame index %d, frame number %d", frameIndex, resultFrameNumber); - //check the reprocessing required flag against the frame number - if (ppInfo == mOfflinePpInfoList.end()) { - LOGE("Error, request for frame number is a reprocess."); - stream->bufDone(frameIndex); - return; - } - - if (IS_BUFFER_ERROR(super_frame->bufs[0]->flags)) { - mChannelCbBufErr(this, resultFrameNumber, - CAMERA3_BUFFER_STATUS_ERROR, mUserData); - } + { + List<PpInfo>::iterator ppInfo; - if (ppInfo->offlinePpFlag) { - mm_camera_super_buf_t *frame = - (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); - if (frame == NULL) { - LOGE("Error allocating memory to save received_frame structure."); - if(stream) { - stream->bufDone(frameIndex); + Mutex::Autolock lock(mOfflinePpLock); + resultFrameNumber = mMemory.getFrameNumber(frameIndex); + for (ppInfo = mOfflinePpInfoList.begin(); + ppInfo != mOfflinePpInfoList.end(); ppInfo++) { + if (ppInfo->frameNumber == (uint32_t)resultFrameNumber) { + break; } + } + LOGD("frame index %d, frame number %d", frameIndex, + resultFrameNumber); + //check the reprocessing required flag against the frame number + if (ppInfo == mOfflinePpInfoList.end()) { + LOGE("Error, request for frame number is a reprocess."); + stream->bufDone(frameIndex); return; } - *frame = *super_frame; - m_postprocessor.processData(frame, ppInfo->output, resultFrameNumber); - free(super_frame); - return; - } else { - if (ppInfo != mOfflinePpInfoList.begin()) { - // There is pending reprocess buffer, cache current buffer - if (ppInfo->callback_buffer != NULL) { - LOGE("Fatal: cached callback_buffer is already present"); + if (ppInfo->offlinePpFlag) { + mm_camera_super_buf_t *frame = + (mm_camera_super_buf_t *)malloc(sizeof( + mm_camera_super_buf_t)); + if (frame == NULL) { + LOGE("Error allocating memory to save received_frame structure."); + if(stream) { + stream->bufDone(frameIndex); + } + return; } - ppInfo->callback_buffer = super_frame; + + *frame = *super_frame; + m_postprocessor.processData(frame, ppInfo->output, + resultFrameNumber); + free(super_frame); return; } else { - mOfflinePpInfoList.erase(ppInfo); + if (ppInfo != mOfflinePpInfoList.begin()) { + // There is pending reprocess buffer, cache current buffer + if (ppInfo->callback_buffer != NULL) { + LOGE("Fatal: cached callback_buffer is already present"); + } + ppInfo->callback_buffer = super_frame; + return; + } else { + mOfflinePpInfoList.erase(ppInfo); + } } } + + if (IS_BUFFER_ERROR(super_frame->bufs[0]->flags)) { + mChannelCbBufErr(this, resultFrameNumber, + CAMERA3_BUFFER_STATUS_ERROR, mUserData); + } + } QCamera3ProcessingChannel::streamCbRoutine(super_frame, stream); |
