QCameraCmdThread.cpp revision 6c6d887243f26c81543d33c2f8aa169862324b40
1/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6*     * Redistributions of source code must retain the above copyright
7*       notice, this list of conditions and the following disclaimer.
8*     * Redistributions in binary form must reproduce the above
9*       copyright notice, this list of conditions and the following
10*       disclaimer in the documentation and/or other materials provided
11*       with the distribution.
12*     * Neither the name of The Linux Foundation nor the names of its
13*       contributors may be used to endorse or promote products derived
14*       from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29
30#include <utils/Errors.h>
31#include <utils/Log.h>
32#include "QCameraCmdThread.h"
33
34using namespace android;
35
36namespace qcamera {
37
38/*===========================================================================
39 * FUNCTION   : QCameraCmdThread
40 *
41 * DESCRIPTION: default constructor of QCameraCmdThread
42 *
43 * PARAMETERS : None
44 *
45 * RETURN     : None
46 *==========================================================================*/
47QCameraCmdThread::QCameraCmdThread() :
48    cmd_queue()
49{
50    cmd_pid = 0;
51    cam_sem_init(&sync_sem, 0);
52    cam_sem_init(&cmd_sem, 0);
53}
54
55/*===========================================================================
56 * FUNCTION   : ~QCameraCmdThread
57 *
58 * DESCRIPTION: deconstructor of QCameraCmdThread
59 *
60 * PARAMETERS : None
61 *
62 * RETURN     : None
63 *==========================================================================*/
64QCameraCmdThread::~QCameraCmdThread()
65{
66    cam_sem_destroy(&sync_sem);
67    cam_sem_destroy(&cmd_sem);
68}
69
70/*===========================================================================
71 * FUNCTION   : launch
72 *
73 * DESCRIPTION: launch Cmd Thread
74 *
75 * PARAMETERS :
76 *   @start_routine : thread routine function ptr
77 *   @user_data     : user data ptr
78 *
79 * RETURN     : int32_t type of status
80 *              NO_ERROR  -- success
81 *              none-zero failure code
82 *==========================================================================*/
83int32_t QCameraCmdThread::launch(void *(*start_routine)(void *),
84                                 void* user_data)
85{
86    /* launch the thread */
87    pthread_create(&cmd_pid,
88                   NULL,
89                   start_routine,
90                   user_data);
91    return NO_ERROR;
92}
93
94/*===========================================================================
95 * FUNCTION   : sendCmd
96 *
97 * DESCRIPTION: send a command to the Cmd Thread
98 *
99 * PARAMETERS :
100 *   @cmd     : command to be executed.
101 *   @sync_cmd: flag to indicate if this is a synchorinzed cmd. If true, this call
102 *              will wait until signal is set after the command is completed.
103 *   @priority: flag to indicate if this is a cmd with priority. If true, the cmd
104 *              will be enqueued to the head with priority.
105 *
106 * RETURN     : int32_t type of status
107 *              NO_ERROR  -- success
108 *              none-zero failure code
109 *==========================================================================*/
110int32_t QCameraCmdThread::sendCmd(camera_cmd_type_t cmd, uint8_t sync_cmd, uint8_t priority)
111{
112    camera_cmd_t *node = (camera_cmd_t *)malloc(sizeof(camera_cmd_t));
113    if (NULL == node) {
114        ALOGE("%s: No memory for camera_cmd_t", __func__);
115        return NO_MEMORY;
116    }
117    memset(node, 0, sizeof(camera_cmd_t));
118    node->cmd = cmd;
119
120    if (priority) {
121        cmd_queue.enqueueWithPriority((void *)node);
122    } else {
123        cmd_queue.enqueue((void *)node);
124    }
125    cam_sem_post(&cmd_sem);
126
127    /* if is a sync call, need to wait until it returns */
128    if (sync_cmd) {
129        cam_sem_wait(&sync_sem);
130    }
131    return NO_ERROR;
132}
133
134/*===========================================================================
135 * FUNCTION   : getCmd
136 *
137 * DESCRIPTION: dequeue a cmommand from cmd queue
138 *
139 * PARAMETERS : None
140 *
141 * RETURN     : cmd dequeued
142 *==========================================================================*/
143camera_cmd_type_t QCameraCmdThread::getCmd()
144{
145    camera_cmd_type_t cmd = CAMERA_CMD_TYPE_NONE;
146    camera_cmd_t *node = (camera_cmd_t *)cmd_queue.dequeue();
147    if (NULL == node) {
148        ALOGD("%s: No notify avail", __func__);
149        return CAMERA_CMD_TYPE_NONE;
150    } else {
151        cmd = node->cmd;
152        free(node);
153    }
154    return cmd;
155}
156
157/*===========================================================================
158 * FUNCTION   : exit
159 *
160 * DESCRIPTION: exit the CMD thread
161 *
162 * PARAMETERS : None
163 *
164 * RETURN     : int32_t type of status
165 *              NO_ERROR  -- success
166 *              none-zero failure code
167 *==========================================================================*/
168int32_t QCameraCmdThread::exit()
169{
170    int32_t rc = NO_ERROR;
171
172    if (cmd_pid == 0) {
173        return rc;
174    }
175
176    rc = sendCmd(CAMERA_CMD_TYPE_EXIT, 0, 1);
177    if (NO_ERROR != rc) {
178        ALOGE("%s: Error during exit, rc = %d", __func__, rc);
179        return rc;
180    }
181
182    /* wait until cmd thread exits */
183    if (pthread_join(cmd_pid, NULL) != 0) {
184        ALOGD("%s: pthread dead already\n", __func__);
185    }
186    cmd_pid = 0;
187    return rc;
188}
189
190}; // namespace qcamera
191