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