tizen beta release
[profile/ivi/gst-openmax0.10.git] / util / async_queue.c
1 /*
2  * Copyright (C) 2008-2009 Nokia Corporation.
3  *
4  * Author: Felipe Contreras <felipe.contreras@nokia.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include <glib.h>
23
24 #include "async_queue.h"
25
26 AsyncQueue *
27 async_queue_new (void)
28 {
29   AsyncQueue *queue;
30
31   queue = g_slice_new0 (AsyncQueue);
32
33   queue->condition = g_cond_new ();
34   queue->mutex = g_mutex_new ();
35   queue->enabled = TRUE;
36
37   return queue;
38 }
39
40 void
41 async_queue_free (AsyncQueue * queue)
42 {
43   g_cond_free (queue->condition);
44   g_mutex_free (queue->mutex);
45
46   g_list_free (queue->head);
47   g_slice_free (AsyncQueue, queue);
48 }
49
50 void
51 async_queue_push (AsyncQueue * queue, gpointer data)
52 {
53   g_mutex_lock (queue->mutex);
54
55   queue->head = g_list_prepend (queue->head, data);
56   if (!queue->tail)
57     queue->tail = queue->head;
58   queue->length++;
59
60   g_cond_signal (queue->condition);
61
62   g_mutex_unlock (queue->mutex);
63 }
64
65 gpointer
66 async_queue_pop (AsyncQueue * queue)
67 {
68   gpointer data = NULL;
69
70   g_mutex_lock (queue->mutex);
71
72   if (!queue->enabled) {
73     /* g_warning ("not enabled!"); */
74     goto leave;
75   }
76
77   if (!queue->tail) {
78     g_cond_wait (queue->condition, queue->mutex);
79   }
80
81   if (queue->tail) {
82     GList *node = queue->tail;
83     data = node->data;
84
85     queue->tail = node->prev;
86     if (queue->tail)
87       queue->tail->next = NULL;
88     else
89       queue->head = NULL;
90     queue->length--;
91     g_list_free_1 (node);
92   }
93
94 leave:
95   g_mutex_unlock (queue->mutex);
96
97   return data;
98 }
99
100 gpointer
101 async_queue_pop_forced (AsyncQueue * queue)
102 {
103   gpointer data = NULL;
104
105   g_mutex_lock (queue->mutex);
106
107   if (queue->tail) {
108     GList *node = queue->tail;
109     data = node->data;
110
111     queue->tail = node->prev;
112     if (queue->tail)
113       queue->tail->next = NULL;
114     else
115       queue->head = NULL;
116     queue->length--;
117     g_list_free_1 (node);
118   }
119
120   g_mutex_unlock (queue->mutex);
121
122   return data;
123 }
124
125 void
126 async_queue_disable (AsyncQueue * queue)
127 {
128   g_mutex_lock (queue->mutex);
129   queue->enabled = FALSE;
130   g_cond_broadcast (queue->condition);
131   g_mutex_unlock (queue->mutex);
132 }
133
134 void
135 async_queue_enable (AsyncQueue * queue)
136 {
137   g_mutex_lock (queue->mutex);
138   queue->enabled = TRUE;
139   g_mutex_unlock (queue->mutex);
140 }
141
142 void
143 async_queue_flush (AsyncQueue * queue)
144 {
145   g_mutex_lock (queue->mutex);
146   g_list_free (queue->head);
147   queue->head = queue->tail = NULL;
148   queue->length = 0;
149   g_mutex_unlock (queue->mutex);
150 }