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 *==========================================================================*/
QCameraQueue()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 *==========================================================================*/
QCameraQueue(release_data_fn data_rel_fn,void * user_data)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 *==========================================================================*/
~QCameraQueue()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 *==========================================================================*/
isEmpty()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 *==========================================================================*/
enqueue(void * data)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 *==========================================================================*/
enqueueWithPriority(void * data)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 *==========================================================================*/
dequeue(bool bFromHead)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 *==========================================================================*/
flush()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 *==========================================================================*/
flushNodes(match_fn match)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