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