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