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