1 /* Copyright (c) 2012-2015, 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 35 using namespace android; 36 37 namespace qcamera { 38 39 /*=========================================================================== 40 * FUNCTION : QCameraCmdThread 41 * 42 * DESCRIPTION: default constructor of QCameraCmdThread 43 * 44 * PARAMETERS : None 45 * 46 * RETURN : None 47 *==========================================================================*/ 48 QCameraCmdThread::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 *==========================================================================*/ 65 QCameraCmdThread::~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 *==========================================================================*/ 84 int32_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 *==========================================================================*/ 107 int32_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 *==========================================================================*/ 130 int32_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 if (!cmd_queue.enqueueWithPriority((void *)node)) { 142 free(node); 143 node = NULL; 144 } 145 } else { 146 if (!cmd_queue.enqueue((void *)node)) { 147 free(node); 148 node = NULL; 149 } 150 } 151 cam_sem_post(&cmd_sem); 152 153 /* if is a sync call, need to wait until it returns */ 154 if (sync_cmd) { 155 cam_sem_wait(&sync_sem); 156 } 157 return NO_ERROR; 158 } 159 160 /*=========================================================================== 161 * FUNCTION : getCmd 162 * 163 * DESCRIPTION: dequeue a cmommand from cmd queue 164 * 165 * PARAMETERS : None 166 * 167 * RETURN : cmd dequeued 168 *==========================================================================*/ 169 camera_cmd_type_t QCameraCmdThread::getCmd() 170 { 171 camera_cmd_type_t cmd = CAMERA_CMD_TYPE_NONE; 172 camera_cmd_t *node = (camera_cmd_t *)cmd_queue.dequeue(); 173 if (NULL == node) { 174 ALOGD("%s: No notify avail", __func__); 175 return CAMERA_CMD_TYPE_NONE; 176 } else { 177 cmd = node->cmd; 178 free(node); 179 } 180 return cmd; 181 } 182 183 /*=========================================================================== 184 * FUNCTION : exit 185 * 186 * DESCRIPTION: exit the CMD thread 187 * 188 * PARAMETERS : None 189 * 190 * RETURN : int32_t type of status 191 * NO_ERROR -- success 192 * none-zero failure code 193 *==========================================================================*/ 194 int32_t QCameraCmdThread::exit() 195 { 196 int32_t rc = NO_ERROR; 197 198 if (cmd_pid == 0) { 199 return rc; 200 } 201 202 rc = sendCmd(CAMERA_CMD_TYPE_EXIT, 0, 1); 203 if (NO_ERROR != rc) { 204 ALOGE("%s: Error during exit, rc = %d", __func__, rc); 205 return rc; 206 } 207 208 /* wait until cmd thread exits */ 209 if (pthread_join(cmd_pid, NULL) != 0) { 210 ALOGD("%s: pthread dead already\n", __func__); 211 } 212 cmd_pid = 0; 213 return rc; 214 } 215 216 }; // namespace qcamera 217