• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <malloc.h>
33 #include <string.h>
34 #include "QCameraQueue.h"
35 
36 namespace qcamera {
37 
38 /*===========================================================================
39  * FUNCTION   : QCameraQueue
40  *
41  * DESCRIPTION: default constructor of QCameraQueue
42  *
43  * PARAMETERS : None
44  *
45  * RETURN     : None
46  *==========================================================================*/
QCameraQueue()47 QCameraQueue::QCameraQueue()
48 {
49     pthread_mutex_init(&m_lock, NULL);
50     cam_list_init(&m_head.list);
51     m_size = 0;
52     m_dataFn = NULL;
53     m_userData = NULL;
54     m_active = true;
55 }
56 
57 /*===========================================================================
58  * FUNCTION   : QCameraQueue
59  *
60  * DESCRIPTION: constructor of QCameraQueue
61  *
62  * PARAMETERS :
63  *   @data_rel_fn : function ptr to release node data internal resource
64  *   @user_data   : user data ptr
65  *
66  * RETURN     : None
67  *==========================================================================*/
QCameraQueue(release_data_fn data_rel_fn,void * user_data)68 QCameraQueue::QCameraQueue(release_data_fn data_rel_fn, void *user_data)
69 {
70     pthread_mutex_init(&m_lock, NULL);
71     cam_list_init(&m_head.list);
72     m_size = 0;
73     m_dataFn = data_rel_fn;
74     m_userData = user_data;
75     m_active = true;
76 }
77 
78 /*===========================================================================
79  * FUNCTION   : ~QCameraQueue
80  *
81  * DESCRIPTION: deconstructor of QCameraQueue
82  *
83  * PARAMETERS : None
84  *
85  * RETURN     : None
86  *==========================================================================*/
~QCameraQueue()87 QCameraQueue::~QCameraQueue()
88 {
89     flush();
90     pthread_mutex_destroy(&m_lock);
91 }
92 
93 /*===========================================================================
94  * FUNCTION   : init
95  *
96  * DESCRIPTION: Put the queue to active state (ready to enqueue and dequeue)
97  *
98  * PARAMETERS : None
99  *
100  * RETURN     : None
101  *==========================================================================*/
init()102 void QCameraQueue::init()
103 {
104     pthread_mutex_lock(&m_lock);
105     m_active = true;
106     pthread_mutex_unlock(&m_lock);
107 }
108 
109 /*===========================================================================
110  * FUNCTION   : isEmpty
111  *
112  * DESCRIPTION: return if the queue is empty or not
113  *
114  * PARAMETERS : None
115  *
116  * RETURN     : true -- queue is empty; false -- not empty
117  *==========================================================================*/
isEmpty()118 bool QCameraQueue::isEmpty()
119 {
120     bool flag = true;
121     pthread_mutex_lock(&m_lock);
122     if (m_size > 0) {
123         flag = false;
124     }
125     pthread_mutex_unlock(&m_lock);
126     return flag;
127 }
128 
129 /*===========================================================================
130  * FUNCTION   : enqueue
131  *
132  * DESCRIPTION: enqueue data into the queue
133  *
134  * PARAMETERS :
135  *   @data    : data to be enqueued
136  *
137  * RETURN     : true -- success; false -- failed
138  *==========================================================================*/
enqueue(void * data)139 bool QCameraQueue::enqueue(void *data)
140 {
141     bool rc;
142     camera_q_node *node =
143         (camera_q_node *)malloc(sizeof(camera_q_node));
144     if (NULL == node) {
145         ALOGE("%s: No memory for camera_q_node", __func__);
146         return false;
147     }
148 
149     memset(node, 0, sizeof(camera_q_node));
150     node->data = data;
151 
152     pthread_mutex_lock(&m_lock);
153     if (m_active) {
154         cam_list_add_tail_node(&node->list, &m_head.list);
155         m_size++;
156         rc = true;
157     } else {
158         free(node);
159         rc = false;
160     }
161     pthread_mutex_unlock(&m_lock);
162     return rc;
163 }
164 
165 /*===========================================================================
166  * FUNCTION   : enqueueWithPriority
167  *
168  * DESCRIPTION: enqueue data into queue with priority, will insert into the
169  *              head of the queue
170  *
171  * PARAMETERS :
172  *   @data    : data to be enqueued
173  *
174  * RETURN     : true -- success; false -- failed
175  *==========================================================================*/
enqueueWithPriority(void * data)176 bool QCameraQueue::enqueueWithPriority(void *data)
177 {
178     bool rc;
179     camera_q_node *node =
180         (camera_q_node *)malloc(sizeof(camera_q_node));
181     if (NULL == node) {
182         ALOGE("%s: No memory for camera_q_node", __func__);
183         return false;
184     }
185 
186     memset(node, 0, sizeof(camera_q_node));
187     node->data = data;
188 
189     pthread_mutex_lock(&m_lock);
190     if (m_active) {
191         struct cam_list *p_next = m_head.list.next;
192 
193         m_head.list.next = &node->list;
194         p_next->prev = &node->list;
195         node->list.next = p_next;
196         node->list.prev = &m_head.list;
197 
198         m_size++;
199         rc = true;
200     } else {
201         free(node);
202         rc = false;
203     }
204     pthread_mutex_unlock(&m_lock);
205     return rc;
206 }
207 
208 /*===========================================================================
209  * FUNCTION   : dequeue
210  *
211  * DESCRIPTION: dequeue data from the queue
212  *
213  * PARAMETERS :
214  *   @bFromHead : if true, dequeue from the head
215  *                if false, dequeue from the tail
216  *
217  * RETURN     : data ptr. NULL if not any data in the queue.
218  *==========================================================================*/
dequeue(bool bFromHead)219 void* QCameraQueue::dequeue(bool bFromHead)
220 {
221     camera_q_node* node = NULL;
222     void* data = NULL;
223     struct cam_list *head = NULL;
224     struct cam_list *pos = NULL;
225 
226     pthread_mutex_lock(&m_lock);
227     if (m_active) {
228         head = &m_head.list;
229         if (bFromHead) {
230             pos = head->next;
231         } else {
232             pos = head->prev;
233         }
234         if (pos != head) {
235             node = member_of(pos, camera_q_node, list);
236             cam_list_del_node(&node->list);
237             m_size--;
238         }
239     }
240     pthread_mutex_unlock(&m_lock);
241 
242     if (NULL != node) {
243         data = node->data;
244         free(node);
245     }
246 
247     return data;
248 }
249 
250 /*===========================================================================
251  * FUNCTION   : flush
252  *
253  * DESCRIPTION: flush all nodes from the queue, queue will be empty after this
254  *              operation.
255  *
256  * PARAMETERS : None
257  *
258  * RETURN     : None
259  *==========================================================================*/
flush()260 void QCameraQueue::flush(){
261     camera_q_node* node = NULL;
262     struct cam_list *head = NULL;
263     struct cam_list *pos = NULL;
264 
265     pthread_mutex_lock(&m_lock);
266     if (m_active) {
267         head = &m_head.list;
268         pos = head->next;
269 
270         while(pos != head) {
271             node = member_of(pos, camera_q_node, list);
272             pos = pos->next;
273             cam_list_del_node(&node->list);
274             m_size--;
275 
276             if (NULL != node->data) {
277                 if (m_dataFn) {
278                     m_dataFn(node->data, m_userData);
279                 }
280                 free(node->data);
281             }
282             free(node);
283 
284         }
285         m_size = 0;
286         m_active = false;
287     }
288     pthread_mutex_unlock(&m_lock);
289 }
290 
291 /*===========================================================================
292  * FUNCTION   : flushNodes
293  *
294  * DESCRIPTION: flush only specific nodes, depending on
295  *              the given matching function.
296  *
297  * PARAMETERS :
298  *   @match   : matching function
299  *
300  * RETURN     : None
301  *==========================================================================*/
flushNodes(match_fn match)302 void QCameraQueue::flushNodes(match_fn match){
303     camera_q_node* node = NULL;
304     struct cam_list *head = NULL;
305     struct cam_list *pos = NULL;
306 
307     if ( NULL == match ) {
308         return;
309     }
310 
311     pthread_mutex_lock(&m_lock);
312     if (m_active) {
313         head = &m_head.list;
314         pos = head->next;
315 
316         while(pos != head) {
317             node = member_of(pos, camera_q_node, list);
318             pos = pos->next;
319             if ( match(node->data, m_userData) ) {
320                 cam_list_del_node(&node->list);
321                 m_size--;
322 
323                 if (NULL != node->data) {
324                     if (m_dataFn) {
325                         m_dataFn(node->data, m_userData);
326                     }
327                     free(node->data);
328                 }
329                 free(node);
330             }
331         }
332     }
333     pthread_mutex_unlock(&m_lock);
334 }
335 
336 /*===========================================================================
337  * FUNCTION   : flushNodes
338  *
339  * DESCRIPTION: flush only specific nodes, depending on
340  *              the given matching function.
341  *
342  * PARAMETERS :
343  *   @match   : matching function
344  *
345  * RETURN     : None
346  *==========================================================================*/
flushNodes(match_fn_data match,void * match_data)347 void QCameraQueue::flushNodes(match_fn_data match, void *match_data){
348     camera_q_node* node = NULL;
349     struct cam_list *head = NULL;
350     struct cam_list *pos = NULL;
351 
352     if ( NULL == match ) {
353         return;
354     }
355 
356     pthread_mutex_lock(&m_lock);
357     if (m_active) {
358         head = &m_head.list;
359         pos = head->next;
360 
361         while(pos != head) {
362             node = member_of(pos, camera_q_node, list);
363             pos = pos->next;
364             if ( match(node->data, m_userData, match_data) ) {
365                 cam_list_del_node(&node->list);
366                 m_size--;
367 
368                 if (NULL != node->data) {
369                     if (m_dataFn) {
370                         m_dataFn(node->data, m_userData);
371                     }
372                     free(node->data);
373                 }
374                 free(node);
375             }
376         }
377     }
378     pthread_mutex_unlock(&m_lock);
379 }
380 
381 }; // namespace qcamera
382