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// Camera dependencies
31#include "mm_qcamera_app.h"
32#include "mm_qcamera_dbg.h"
33
34int mm_camera_queue_init(mm_camera_queue_t *queue,
35                         release_data_fn data_rel_fn,
36                         void *user_data)
37{
38    if ( NULL == queue ) {
39        return -1;
40    }
41
42    pthread_mutex_init(&queue->m_lock, NULL);
43    cam_list_init(&queue->m_head.list);
44    queue->m_size = 0;
45    queue->m_dataFn = data_rel_fn;
46    queue->m_userData = user_data;
47
48    return MM_CAMERA_OK;
49}
50
51int mm_qcamera_queue_release(mm_camera_queue_t *queue)
52{
53    if ( NULL == queue ) {
54        return -1;
55    }
56
57    mm_qcamera_queue_flush(queue);
58    pthread_mutex_destroy(&queue->m_lock);
59
60    return MM_CAMERA_OK;
61}
62
63int mm_qcamera_queue_isempty(mm_camera_queue_t *queue)
64{
65    if ( NULL == queue ) {
66        return 0;
67    }
68
69    int flag = 1;
70    pthread_mutex_lock(&queue->m_lock);
71    if (queue->m_size > 0) {
72        flag = 0;
73    }
74    pthread_mutex_unlock(&queue->m_lock);
75
76    return flag;
77}
78
79int mm_qcamera_queue_enqueue(mm_camera_queue_t *queue, void *data)
80{
81    if ( NULL == queue ) {
82        return -1;
83    }
84
85    camera_q_node *node =
86        (camera_q_node *)malloc(sizeof(camera_q_node));
87    if (NULL == node) {
88        LOGE(" No memory for camera_q_node");
89        return 0;
90    }
91
92    memset(node, 0, sizeof(camera_q_node));
93    node->data = data;
94
95    pthread_mutex_lock(&queue->m_lock);
96    cam_list_add_tail_node(&node->list, &queue->m_head.list);
97    queue->m_size++;
98    pthread_mutex_unlock(&queue->m_lock);
99
100    return 1;
101}
102
103void* mm_qcamera_queue_dequeue(mm_camera_queue_t *queue, int bFromHead)
104{
105    if ( NULL == queue ) {
106        return NULL;
107    }
108
109    camera_q_node* node = NULL;
110    void* data = NULL;
111    struct cam_list *head = NULL;
112    struct cam_list *pos = NULL;
113
114    pthread_mutex_lock(&queue->m_lock);
115    head = &queue->m_head.list;
116    if (bFromHead) {
117        pos = head->next;
118    } else {
119        pos = head->prev;
120    }
121    if (pos != head) {
122        node = member_of(pos, camera_q_node, list);
123        cam_list_del_node(&node->list);
124        queue->m_size--;
125    }
126    pthread_mutex_unlock(&queue->m_lock);
127
128    if (NULL != node) {
129        data = node->data;
130        free(node);
131    }
132
133    return data;
134}
135
136void mm_qcamera_queue_flush(mm_camera_queue_t *queue)
137{
138    camera_q_node* node = NULL;
139    struct cam_list *head = NULL;
140    struct cam_list *pos = NULL;
141
142    if ( NULL == queue ) {
143        return;
144    }
145
146    pthread_mutex_lock(&queue->m_lock);
147    head = &queue->m_head.list;
148    pos = head->next;
149
150    while(pos != head) {
151        node = member_of(pos, camera_q_node, list);
152        pos = pos->next;
153        cam_list_del_node(&node->list);
154        queue->m_size--;
155
156        if (NULL != node->data) {
157            if (queue->m_dataFn) {
158                queue->m_dataFn(node->data, queue->m_userData);
159            }
160            free(node->data);
161        }
162        free(node);
163
164    }
165    queue->m_size = 0;
166    pthread_mutex_unlock(&queue->m_lock);
167}
168
169