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