QCameraCmdThread.cpp revision 6a225c824c49ff9ecdc4b67c802f1af272569e03
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 <sys/prctl.h>
33#include "QCameraCmdThread.h"
34
35using namespace android;
36
37namespace qcamera {
38
39/*===========================================================================
40 * FUNCTION   : QCameraCmdThread
41 *
42 * DESCRIPTION: default constructor of QCameraCmdThread
43 *
44 * PARAMETERS : None
45 *
46 * RETURN     : None
47 *==========================================================================*/
48QCameraCmdThread::QCameraCmdThread() :
49    cmd_queue()
50{
51    cmd_pid = 0;
52    cam_sem_init(&sync_sem, 0);
53    cam_sem_init(&cmd_sem, 0);
54}
55
56/*===========================================================================
57 * FUNCTION   : ~QCameraCmdThread
58 *
59 * DESCRIPTION: deconstructor of QCameraCmdThread
60 *
61 * PARAMETERS : None
62 *
63 * RETURN     : None
64 *==========================================================================*/
65QCameraCmdThread::~QCameraCmdThread()
66{
67    cam_sem_destroy(&sync_sem);
68    cam_sem_destroy(&cmd_sem);
69}
70
71/*===========================================================================
72 * FUNCTION   : launch
73 *
74 * DESCRIPTION: launch Cmd Thread
75 *
76 * PARAMETERS :
77 *   @start_routine : thread routine function ptr
78 *   @user_data     : user data ptr
79 *
80 * RETURN     : int32_t type of status
81 *              NO_ERROR  -- success
82 *              none-zero failure code
83 *==========================================================================*/
84int32_t QCameraCmdThread::launch(void *(*start_routine)(void *),
85                                 void* user_data)
86{
87    /* launch the thread */
88    pthread_create(&cmd_pid,
89                   NULL,
90                   start_routine,
91                   user_data);
92    return NO_ERROR;
93}
94
95/*===========================================================================
96 * FUNCTION   : setName
97 *
98 * DESCRIPTION: name the cmd thread
99 *
100 * PARAMETERS :
101 *   @name : desired name for the thread
102 *
103 * RETURN     : int32_t type of status
104 *              NO_ERROR  -- success
105 *              none-zero failure code
106 *==========================================================================*/
107int32_t QCameraCmdThread::setName(const char* name)
108{
109    /* name the thread */
110    prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
111    return NO_ERROR;
112}
113
114/*===========================================================================
115 * FUNCTION   : sendCmd
116 *
117 * DESCRIPTION: send a command to the Cmd Thread
118 *
119 * PARAMETERS :
120 *   @cmd     : command to be executed.
121 *   @sync_cmd: flag to indicate if this is a synchorinzed cmd. If true, this call
122 *              will wait until signal is set after the command is completed.
123 *   @priority: flag to indicate if this is a cmd with priority. If true, the cmd
124 *              will be enqueued to the head with priority.
125 *
126 * RETURN     : int32_t type of status
127 *              NO_ERROR  -- success
128 *              none-zero failure code
129 *==========================================================================*/
130int32_t QCameraCmdThread::sendCmd(camera_cmd_type_t cmd, uint8_t sync_cmd, uint8_t priority)
131{
132    camera_cmd_t *node = (camera_cmd_t *)malloc(sizeof(camera_cmd_t));
133    if (NULL == node) {
134        ALOGE("%s: No memory for camera_cmd_t", __func__);
135        return NO_MEMORY;
136    }
137    memset(node, 0, sizeof(camera_cmd_t));
138    node->cmd = cmd;
139
140    if (priority) {
141        cmd_queue.enqueueWithPriority((void *)node);
142    } else {
143        cmd_queue.enqueue((void *)node);
144    }
145    cam_sem_post(&cmd_sem);
146
147    /* if is a sync call, need to wait until it returns */
148    if (sync_cmd) {
149        cam_sem_wait(&sync_sem);
150    }
151    return NO_ERROR;
152}
153
154/*===========================================================================
155 * FUNCTION   : getCmd
156 *
157 * DESCRIPTION: dequeue a cmommand from cmd queue
158 *
159 * PARAMETERS : None
160 *
161 * RETURN     : cmd dequeued
162 *==========================================================================*/
163camera_cmd_type_t QCameraCmdThread::getCmd()
164{
165    camera_cmd_type_t cmd = CAMERA_CMD_TYPE_NONE;
166    camera_cmd_t *node = (camera_cmd_t *)cmd_queue.dequeue();
167    if (NULL == node) {
168        ALOGD("%s: No notify avail", __func__);
169        return CAMERA_CMD_TYPE_NONE;
170    } else {
171        cmd = node->cmd;
172        free(node);
173    }
174    return cmd;
175}
176
177/*===========================================================================
178 * FUNCTION   : exit
179 *
180 * DESCRIPTION: exit the CMD thread
181 *
182 * PARAMETERS : None
183 *
184 * RETURN     : int32_t type of status
185 *              NO_ERROR  -- success
186 *              none-zero failure code
187 *==========================================================================*/
188int32_t QCameraCmdThread::exit()
189{
190    int32_t rc = NO_ERROR;
191
192    if (cmd_pid == 0) {
193        return rc;
194    }
195
196    rc = sendCmd(CAMERA_CMD_TYPE_EXIT, 0, 1);
197    if (NO_ERROR != rc) {
198        ALOGE("%s: Error during exit, rc = %d", __func__, rc);
199        return rc;
200    }
201
202    /* wait until cmd thread exits */
203    if (pthread_join(cmd_pid, NULL) != 0) {
204        ALOGD("%s: pthread dead already\n", __func__);
205    }
206    cmd_pid = 0;
207    return rc;
208}
209
210}; // namespace qcamera
211