summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShuzhen Wang <shuzhenw@codeaurora.org>2014-04-15 10:01:20 -0700
committerAli B <abittin@gmail.com>2018-06-17 19:16:29 +0300
commitb57eb29dbb7d8c4233fb5e5e024aa31271849a1f (patch)
treefbaeeefebb21035a25571c6722f8fc2b2634f2a1
parent3ce6ff73a744b3e804ca8378464c8b2a778e382b (diff)
QCamera2: Sync stream stop with poll updates
The stream command thread will be released as part of the stream stop but the channel poll thread can still run until the channel is released. In this case the synchronous poll delete during stream stop can fail if the asynchronous poll version got triggered immediately before that. The stop will proceed and release the stream command thread resources before the async poll update could be processed. The poll thread could then try and access the command thread resources resulting in a crash. The failing sync poll delete should be handled by syncing to the poll thread again and allowing any previously pending async updates to be processed before releasing any resources. Bug: 14028116 CRs-Fixed: 629996 Change-Id: Ib6252445731d05c01a59503b3cfe70ef089a4ffd
-rwxr-xr-xcamera/QCamera2/stack/mm-camera-interface/inc/mm_camera.h2
-rwxr-xr-xcamera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c12
-rwxr-xr-xcamera/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c27
3 files changed, 39 insertions, 2 deletions
diff --git a/camera/QCamera2/stack/mm-camera-interface/inc/mm_camera.h b/camera/QCamera2/stack/mm-camera-interface/inc/mm_camera.h
index 1d51c98..7f0a837 100755
--- a/camera/QCamera2/stack/mm-camera-interface/inc/mm_camera.h
+++ b/camera/QCamera2/stack/mm-camera-interface/inc/mm_camera.h
@@ -567,6 +567,8 @@ extern int32_t mm_camera_poll_thread_del_poll_fd(
mm_camera_poll_thread_t * poll_cb,
uint32_t handler,
mm_camera_call_type_t);
+extern int32_t mm_camera_poll_thread_commit_updates(
+ mm_camera_poll_thread_t * poll_cb);
extern int32_t mm_camera_cmd_thread_launch(
mm_camera_cmd_thread_t * cmd_thread,
mm_camera_cmd_cb_t cb,
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
index df1c938..ad407b4 100755
--- a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
@@ -910,7 +910,17 @@ int32_t mm_stream_streamoff(mm_stream_t *my_obj)
__func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
/* step1: remove fd from data poll thread */
- mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl, mm_camera_sync_call);
+ rc = mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
+ my_obj->my_hdl, mm_camera_sync_call);
+ if (rc < 0) {
+ /* The error might be due to async update. In this case
+ * wait for all updates to complete before proceeding. */
+ rc = mm_camera_poll_thread_commit_updates(&my_obj->ch_obj->poll_thread[0]);
+ if (rc < 0) {
+ CDBG_ERROR("%s: Poll sync failed %d",
+ __func__, rc);
+ }
+ }
/* step2: stream off */
rc = ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c
index bac0168..8596fc9 100755
--- a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c
@@ -45,6 +45,8 @@ typedef enum {
MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED,
/* poll entries updated */
MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED_ASYNC,
+ /* commit updates */
+ MM_CAMERA_PIPE_CMD_COMMIT,
/* exit */
MM_CAMERA_PIPE_CMD_EXIT,
/* max count */
@@ -251,6 +253,9 @@ static void mm_camera_poll_proc_pipe(mm_camera_poll_thread_t *poll_cb)
mm_camera_poll_sig_done(poll_cb);
break;
+ case MM_CAMERA_PIPE_CMD_COMMIT:
+ mm_camera_poll_sig_done(poll_cb);
+ break;
case MM_CAMERA_PIPE_CMD_EXIT:
default:
mm_camera_poll_set_state(poll_cb, MM_CAMERA_POLL_TASK_STATE_STOPPED);
@@ -357,6 +362,23 @@ int32_t mm_camera_poll_thread_notify_entries_updated(mm_camera_poll_thread_t * p
}
/*===========================================================================
+ * FUNCTION : mm_camera_poll_thread_commit_updates
+ *
+ * DESCRIPTION: sync with all previously pending async updates
+ *
+ * PARAMETERS :
+ * @poll_cb : ptr to poll thread object
+ *
+ * RETURN : int32_t type of status
+ * 0 -- success
+ * -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_poll_thread_commit_updates(mm_camera_poll_thread_t * poll_cb)
+{
+ return mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_COMMIT);
+}
+
+/*===========================================================================
* FUNCTION : mm_camera_poll_thread_add_poll_fd
*
* DESCRIPTION: add a new fd into polling thread
@@ -418,7 +440,9 @@ int32_t mm_camera_poll_thread_add_poll_fd(mm_camera_poll_thread_t * poll_cb,
* @handler : stream handle if channel data polling thread,
* 0 if event polling thread
*
- * RETURN : none
+ * RETURN : int32_t type of status
+ * 0 -- success
+ * -1 -- failure
*==========================================================================*/
int32_t mm_camera_poll_thread_del_poll_fd(mm_camera_poll_thread_t * poll_cb,
uint32_t handler,
@@ -451,6 +475,7 @@ int32_t mm_camera_poll_thread_del_poll_fd(mm_camera_poll_thread_t * poll_cb,
} else {
CDBG_ERROR("%s: invalid handler %d (%d)",
__func__, handler, idx);
+ return -1;
}
return rc;