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