1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * GAsyncQueue: asyncronous queue implementation, based on Gqueue.
5 * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
34 guint waiting_threads;
41 GAsyncQueue* retval = g_new (GAsyncQueue, 1);
42 retval->mutex = g_mutex_new ();
43 retval->cond = g_cond_new ();
44 retval->queue = g_queue_new ();
45 retval->waiting_threads = 0;
46 retval->ref_count = 1;
51 g_async_queue_ref (GAsyncQueue *queue)
53 g_return_if_fail (queue);
54 g_return_if_fail (queue->ref_count > 0);
56 g_mutex_lock (queue->mutex);
58 g_mutex_unlock (queue->mutex);
62 g_async_queue_ref_unlocked (GAsyncQueue *queue)
64 g_return_if_fail (queue);
65 g_return_if_fail (queue->ref_count > 0);
71 g_async_queue_unref_and_unlock (GAsyncQueue *queue)
75 g_return_if_fail (queue);
76 g_return_if_fail (queue->ref_count > 0);
79 stop = (queue->ref_count == 0);
80 g_mutex_unlock (queue->mutex);
84 g_return_if_fail (queue->waiting_threads == 0);
85 g_mutex_free (queue->mutex);
86 g_cond_free (queue->cond);
87 g_queue_free (queue->queue);
93 g_async_queue_unref (GAsyncQueue *queue)
95 g_return_if_fail (queue);
96 g_return_if_fail (queue->ref_count > 0);
98 g_mutex_lock (queue->mutex);
99 g_async_queue_unref_and_unlock (queue);
103 g_async_queue_lock (GAsyncQueue *queue)
105 g_return_if_fail (queue);
106 g_return_if_fail (queue->ref_count > 0);
108 g_mutex_lock (queue->mutex);
112 g_async_queue_unlock (GAsyncQueue *queue)
114 g_return_if_fail (queue);
115 g_return_if_fail (queue->ref_count > 0);
117 g_mutex_unlock (queue->mutex);
121 g_async_queue_push (GAsyncQueue* queue, gpointer data)
123 g_return_if_fail (queue);
124 g_return_if_fail (queue->ref_count > 0);
125 g_return_if_fail (data);
127 g_mutex_lock (queue->mutex);
128 g_async_queue_push_unlocked (queue, data);
129 g_mutex_unlock (queue->mutex);
133 g_async_queue_push_unlocked (GAsyncQueue* queue, gpointer data)
135 g_return_if_fail (queue);
136 g_return_if_fail (queue->ref_count > 0);
137 g_return_if_fail (data);
139 g_queue_push_head (queue->queue, data);
140 g_cond_signal (queue->cond);
144 g_async_queue_pop_intern_unlocked (GAsyncQueue* queue, gboolean try,
149 if (!g_queue_peek_tail (queue->queue))
155 queue->waiting_threads++;
156 while (!g_queue_peek_tail (queue->queue))
157 g_cond_wait(queue->cond, queue->mutex);
158 queue->waiting_threads--;
162 queue->waiting_threads++;
163 while (!g_queue_peek_tail (queue->queue))
164 if (!g_cond_timed_wait (queue->cond, queue->mutex, end_time))
166 queue->waiting_threads--;
167 if (!g_queue_peek_tail (queue->queue))
172 retval = g_queue_pop_tail (queue->queue);
180 g_async_queue_pop (GAsyncQueue* queue)
184 g_return_val_if_fail (queue, NULL);
185 g_return_val_if_fail (queue->ref_count > 0, NULL);
187 g_mutex_lock (queue->mutex);
188 retval = g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
189 g_mutex_unlock (queue->mutex);
195 g_async_queue_pop_unlocked (GAsyncQueue* queue)
197 g_return_val_if_fail (queue, NULL);
198 g_return_val_if_fail (queue->ref_count > 0, NULL);
200 return g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
204 g_async_queue_try_pop (GAsyncQueue* queue)
208 g_return_val_if_fail (queue, NULL);
209 g_return_val_if_fail (queue->ref_count > 0, NULL);
211 g_mutex_lock (queue->mutex);
212 retval = g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
213 g_mutex_unlock (queue->mutex);
219 g_async_queue_try_pop_unlocked (GAsyncQueue* queue)
221 g_return_val_if_fail (queue, NULL);
222 g_return_val_if_fail (queue->ref_count > 0, NULL);
224 return g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
228 g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time)
232 g_return_val_if_fail (queue, NULL);
233 g_return_val_if_fail (queue->ref_count > 0, NULL);
235 g_mutex_lock (queue->mutex);
236 retval = g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
237 g_mutex_unlock (queue->mutex);
243 g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time)
245 g_return_val_if_fail (queue, NULL);
246 g_return_val_if_fail (queue->ref_count > 0, NULL);
248 return g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
252 g_async_queue_length_unlocked (GAsyncQueue* queue)
254 g_return_val_if_fail (queue, 0);
255 g_return_val_if_fail (queue->ref_count > 0, 0);
257 return queue->queue->length - queue->waiting_threads;
261 g_async_queue_length(GAsyncQueue* queue)
265 g_return_val_if_fail (queue, 0);
266 g_return_val_if_fail (queue->ref_count > 0, 0);
268 g_mutex_lock (queue->mutex);
269 retval = queue->queue->length - queue->waiting_threads;
270 g_mutex_unlock (queue->mutex);