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 34namespace qcamera { 35 36/*=========================================================================== 37 * FUNCTION : QCameraQueue 38 * 39 * DESCRIPTION: default constructor of QCameraQueue 40 * 41 * PARAMETERS : None 42 * 43 * RETURN : None 44 *==========================================================================*/ 45QCameraQueue::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 *==========================================================================*/ 65QCameraQueue::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 *==========================================================================*/ 83QCameraQueue::~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 *==========================================================================*/ 98bool 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 *==========================================================================*/ 119bool 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 *==========================================================================*/ 149bool 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 *==========================================================================*/ 185void* 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 *==========================================================================*/ 224void 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 *==========================================================================*/ 263void 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