Home | History | Annotate | Download | only in util
      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