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 34 using namespace android; 35 36 namespace qcamera { 37 38 /*=========================================================================== 39 * FUNCTION : QCameraCmdThread 40 * 41 * DESCRIPTION: default constructor of QCameraCmdThread 42 * 43 * PARAMETERS : None 44 * 45 * RETURN : None 46 *==========================================================================*/ 47 QCameraCmdThread::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 *==========================================================================*/ 64 QCameraCmdThread::~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 *==========================================================================*/ 83 int32_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 *==========================================================================*/ 110 int32_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 *==========================================================================*/ 143 camera_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 *==========================================================================*/ 168 int32_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