1 /* Copyright (c) 2012, 2016, The Linux Foundation. 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 // System dependencies
31 #include <pthread.h>
32 
33 // Camera dependencies
34 #include "cam_list.h"
35 
36 typedef struct {
37     struct cam_list list;
38     void *data;
39 } cam_node_t;
40 
41 typedef struct {
42     cam_node_t head; /* dummy head */
43     uint32_t size;
44     pthread_mutex_t lock;
45 } cam_queue_t;
46 
cam_queue_init(cam_queue_t * queue)47 static inline int32_t cam_queue_init(cam_queue_t *queue)
48 {
49     pthread_mutex_init(&queue->lock, NULL);
50     cam_list_init(&queue->head.list);
51     queue->size = 0;
52     return 0;
53 }
54 
cam_queue_enq(cam_queue_t * queue,void * data)55 static inline int32_t cam_queue_enq(cam_queue_t *queue, void *data)
56 {
57     cam_node_t *node =
58         (cam_node_t *)malloc(sizeof(cam_node_t));
59     if (NULL == node) {
60         return -1;
61     }
62 
63     memset(node, 0, sizeof(cam_node_t));
64     node->data = data;
65 
66     pthread_mutex_lock(&queue->lock);
67     cam_list_add_tail_node(&node->list, &queue->head.list);
68     queue->size++;
69     pthread_mutex_unlock(&queue->lock);
70 
71     return 0;
72 }
73 
cam_queue_deq(cam_queue_t * queue)74 static inline void *cam_queue_deq(cam_queue_t *queue)
75 {
76     cam_node_t *node = NULL;
77     void *data = NULL;
78     struct cam_list *head = NULL;
79     struct cam_list *pos = NULL;
80 
81     pthread_mutex_lock(&queue->lock);
82     head = &queue->head.list;
83     pos = head->next;
84     if (pos != head) {
85         node = member_of(pos, cam_node_t, list);
86         cam_list_del_node(&node->list);
87         queue->size--;
88     }
89     pthread_mutex_unlock(&queue->lock);
90 
91     if (NULL != node) {
92         data = node->data;
93         free(node);
94     }
95 
96     return data;
97 }
98 
cam_queue_flush(cam_queue_t * queue)99 static inline int32_t cam_queue_flush(cam_queue_t *queue)
100 {
101     cam_node_t *node = NULL;
102     struct cam_list *head = NULL;
103     struct cam_list *pos = NULL;
104 
105     pthread_mutex_lock(&queue->lock);
106     head = &queue->head.list;
107     pos = head->next;
108 
109     while(pos != head) {
110         node = member_of(pos, cam_node_t, list);
111         pos = pos->next;
112         cam_list_del_node(&node->list);
113         queue->size--;
114 
115         /* TODO later to consider ptr inside data */
116         /* for now we only assume there is no ptr inside data
117          * so we free data directly */
118         if (NULL != node->data) {
119             free(node->data);
120         }
121         free(node);
122 
123     }
124     queue->size = 0;
125     pthread_mutex_unlock(&queue->lock);
126     return 0;
127 }
128 
cam_queue_deinit(cam_queue_t * queue)129 static inline int32_t cam_queue_deinit(cam_queue_t *queue)
130 {
131     cam_queue_flush(queue);
132     pthread_mutex_destroy(&queue->lock);
133     return 0;
134 }
135