Home | History | Annotate | Download | only in util
      1 /* Copyright (c) 2012, 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 "QCameraQueue.h"
     33 
     34 namespace qcamera {
     35 
     36 /*===========================================================================
     37  * FUNCTION   : QCameraQueue
     38  *
     39  * DESCRIPTION: default constructor of QCameraQueue
     40  *
     41  * PARAMETERS : None
     42  *
     43  * RETURN     : None
     44  *==========================================================================*/
     45 QCameraQueue::QCameraQueue()
     46 {
     47     pthread_mutex_init(&m_lock, NULL);
     48     cam_list_init(&m_head.list);
     49     m_size = 0;
     50     m_dataFn = NULL;
     51     m_userData = NULL;
     52 }
     53 
     54 /*===========================================================================
     55  * FUNCTION   : QCameraQueue
     56  *
     57  * DESCRIPTION: constructor of QCameraQueue
     58  *
     59  * PARAMETERS :
     60  *   @data_rel_fn : function ptr to release node data internal resource
     61  *   @user_data   : user data ptr
     62  *
     63  * RETURN     : None
     64  *==========================================================================*/
     65 QCameraQueue::QCameraQueue(release_data_fn data_rel_fn, void *user_data)
     66 {
     67     pthread_mutex_init(&m_lock, NULL);
     68     cam_list_init(&m_head.list);
     69     m_size = 0;
     70     m_dataFn = data_rel_fn;
     71     m_userData = user_data;
     72 }
     73 
     74 /*===========================================================================
     75  * FUNCTION   : ~QCameraQueue
     76  *
     77  * DESCRIPTION: deconstructor of QCameraQueue
     78  *
     79  * PARAMETERS : None
     80  *
     81  * RETURN     : None
     82  *==========================================================================*/
     83 QCameraQueue::~QCameraQueue()
     84 {
     85     flush();
     86     pthread_mutex_destroy(&m_lock);
     87 }
     88 
     89 /*===========================================================================
     90  * FUNCTION   : isEmpty
     91  *
     92  * DESCRIPTION: return if the queue is empty or not
     93  *
     94  * PARAMETERS : None
     95  *
     96  * RETURN     : true -- queue is empty; false -- not empty
     97  *==========================================================================*/
     98 bool QCameraQueue::isEmpty()
     99 {
    100     bool flag = true;
    101     pthread_mutex_lock(&m_lock);
    102     if (m_size > 0) {
    103         flag = false;
    104     }
    105     pthread_mutex_unlock(&m_lock);
    106     return flag;
    107 }
    108 
    109 /*===========================================================================
    110  * FUNCTION   : enqueue
    111  *
    112  * DESCRIPTION: enqueue data into the queue
    113  *
    114  * PARAMETERS :
    115  *   @data    : data to be enqueued
    116  *
    117  * RETURN     : true -- success; false -- failed
    118  *==========================================================================*/
    119 bool QCameraQueue::enqueue(void *data)
    120 {
    121     camera_q_node *node =
    122         (camera_q_node *)malloc(sizeof(camera_q_node));
    123     if (NULL == node) {
    124         ALOGE("%s: No memory for camera_q_node", __func__);
    125         return false;
    126     }
    127 
    128     memset(node, 0, sizeof(camera_q_node));
    129     node->data = data;
    130 
    131     pthread_mutex_lock(&m_lock);
    132     cam_list_add_tail_node(&node->list, &m_head.list);
    133     m_size++;
    134     pthread_mutex_unlock(&m_lock);
    135     return true;
    136 }
    137 
    138 /*===========================================================================
    139  * FUNCTION   : enqueueWithPriority
    140  *
    141  * DESCRIPTION: enqueue data into queue with priority, will insert into the
    142  *              head of the queue
    143  *
    144  * PARAMETERS :
    145  *   @data    : data to be enqueued
    146  *
    147  * RETURN     : true -- success; false -- failed
    148  *==========================================================================*/
    149 bool QCameraQueue::enqueueWithPriority(void *data)
    150 {
    151     camera_q_node *node =
    152         (camera_q_node *)malloc(sizeof(camera_q_node));
    153     if (NULL == node) {
    154         ALOGE("%s: No memory for camera_q_node", __func__);
    155         return false;
    156     }
    157 
    158     memset(node, 0, sizeof(camera_q_node));
    159     node->data = data;
    160 
    161     pthread_mutex_lock(&m_lock);
    162     struct cam_list *p_next = m_head.list.next;
    163 
    164     m_head.list.next = &node->list;
    165     p_next->prev = &node->list;
    166     node->list.next = p_next;
    167     node->list.prev = &m_head.list;
    168 
    169     m_size++;
    170     pthread_mutex_unlock(&m_lock);
    171     return true;
    172 }
    173 
    174 /*===========================================================================
    175  * FUNCTION   : dequeue
    176  *
    177  * DESCRIPTION: dequeue data from the queue
    178  *
    179  * PARAMETERS :
    180  *   @bFromHead : if true, dequeue from the head
    181  *                if false, dequeue from the tail
    182  *
    183  * RETURN     : data ptr. NULL if not any data in the queue.
    184  *==========================================================================*/
    185 void* QCameraQueue::dequeue(bool bFromHead)
    186 {
    187     camera_q_node* node = NULL;
    188     void* data = NULL;
    189     struct cam_list *head = NULL;
    190     struct cam_list *pos = NULL;
    191 
    192     pthread_mutex_lock(&m_lock);
    193     head = &m_head.list;
    194     if (bFromHead) {
    195         pos = head->next;
    196     } else {
    197         pos = head->prev;
    198     }
    199     if (pos != head) {
    200         node = member_of(pos, camera_q_node, list);
    201         cam_list_del_node(&node->list);
    202         m_size--;
    203     }
    204     pthread_mutex_unlock(&m_lock);
    205 
    206     if (NULL != node) {
    207         data = node->data;
    208         free(node);
    209     }
    210 
    211     return data;
    212 }
    213 
    214 /*===========================================================================
    215  * FUNCTION   : flush
    216  *
    217  * DESCRIPTION: flush all nodes from the queue, queue will be empty after this
    218  *              operation.
    219  *
    220  * PARAMETERS : None
    221  *
    222  * RETURN     : None
    223  *==========================================================================*/
    224 void QCameraQueue::flush(){
    225     camera_q_node* node = NULL;
    226     struct cam_list *head = NULL;
    227     struct cam_list *pos = NULL;
    228 
    229     pthread_mutex_lock(&m_lock);
    230     head = &m_head.list;
    231     pos = head->next;
    232 
    233     while(pos != head) {
    234         node = member_of(pos, camera_q_node, list);
    235         pos = pos->next;
    236         cam_list_del_node(&node->list);
    237         m_size--;
    238 
    239         if (NULL != node->data) {
    240             if (m_dataFn) {
    241                 m_dataFn(node->data, m_userData);
    242             }
    243             free(node->data);
    244         }
    245         free(node);
    246 
    247     }
    248     m_size = 0;
    249     pthread_mutex_unlock(&m_lock);
    250 }
    251 
    252 /*===========================================================================
    253  * FUNCTION   : flushNodes
    254  *
    255  * DESCRIPTION: flush only specific nodes, depending on
    256  *              the given matching function.
    257  *
    258  * PARAMETERS :
    259  *   @match   : matching function
    260  *
    261  * RETURN     : None
    262  *==========================================================================*/
    263 void QCameraQueue::flushNodes(match_fn match){
    264     camera_q_node* node = NULL;
    265     struct cam_list *head = NULL;
    266     struct cam_list *pos = NULL;
    267 
    268     if ( NULL == match ) {
    269         return;
    270     }
    271 
    272     pthread_mutex_lock(&m_lock);
    273     head = &m_head.list;
    274     pos = head->next;
    275 
    276     while(pos != head) {
    277         node = member_of(pos, camera_q_node, list);
    278         pos = pos->next;
    279         if ( match(node->data, m_userData) ) {
    280             cam_list_del_node(&node->list);
    281             m_size--;
    282 
    283             if (NULL != node->data) {
    284                 if (m_dataFn) {
    285                     m_dataFn(node->data, m_userData);
    286                 }
    287                 free(node->data);
    288             }
    289             free(node);
    290         }
    291     }
    292     pthread_mutex_unlock(&m_lock);
    293 }
    294 
    295 }; // namespace qcamera
    296