From 91b9b2dd126c16b77e86bdaf5ff82b1cc3c97ab8 Mon Sep 17 00:00:00 2001 From: Sebastian Wilhelmi Date: Thu, 2 Nov 2000 14:54:52 +0000 Subject: [PATCH] Added documentation for asynchronous queues. 2000-11-02 Sebastian Wilhelmi * glib/tmpl/async_queues.sgml, glib/glib-sections.txt: Added documentation for asynchronous queues. * gasyncqueue.c: Added inline documentation for asyncronous queues. --- ChangeLog | 2 + ChangeLog.pre-2-0 | 2 + ChangeLog.pre-2-10 | 2 + ChangeLog.pre-2-12 | 2 + ChangeLog.pre-2-2 | 2 + ChangeLog.pre-2-4 | 2 + ChangeLog.pre-2-6 | 2 + ChangeLog.pre-2-8 | 2 + docs/reference/ChangeLog | 5 + docs/reference/glib/glib-sections.txt | 16 +-- docs/reference/glib/tmpl/async_queues.sgml | 135 ++++++++++++--------- gasyncqueue.c | 185 +++++++++++++++++++++++++++-- glib/gasyncqueue.c | 185 +++++++++++++++++++++++++++-- 13 files changed, 454 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1653b3..179ca87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index d1653b3..179ca87 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d1653b3..179ca87 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index d1653b3..179ca87 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index d1653b3..179ca87 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d1653b3..179ca87 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d1653b3..179ca87 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d1653b3..179ca87 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,5 +1,7 @@ 2000-11-02 Sebastian Wilhelmi + * gasyncqueue.c: Added documentation for asyncronous queues. + * gspawn.c: Include sys/select.h (some platforms need it for select). diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 1eea125..3617681 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,8 @@ +2000-11-02 Sebastian Wilhelmi + + * glib/tmpl/async_queues.sgml, glib/glib-sections.txt: Added + documentation for asynchronous queues. + 2000-10-31 Sebastian Wilhelmi * glib/tmpl/linked_lists_single.sgml: This time the right fix. diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index fb17406..1892b44 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -513,21 +513,23 @@ g_thread_pool_stop_unused_threads async_queues GAsyncQueue g_async_queue_new +g_async_queue_ref +g_async_queue_unref +g_async_queue_push +g_async_queue_pop +g_async_queue_try_pop +g_async_queue_timed_pop +g_async_queue_length + + g_async_queue_lock g_async_queue_unlock -g_async_queue_ref g_async_queue_ref_unlocked -g_async_queue_unref g_async_queue_unref_and_unlock -g_async_queue_push g_async_queue_push_unlocked -g_async_queue_pop g_async_queue_pop_unlocked -g_async_queue_try_pop g_async_queue_try_pop_unlocked -g_async_queue_timed_pop g_async_queue_timed_pop_unlocked -g_async_queue_length g_async_queue_length_unlocked diff --git a/docs/reference/glib/tmpl/async_queues.sgml b/docs/reference/glib/tmpl/async_queues.sgml index 3065103..3e2926b 100644 --- a/docs/reference/glib/tmpl/async_queues.sgml +++ b/docs/reference/glib/tmpl/async_queues.sgml @@ -2,11 +2,60 @@ Asynchronous Queues - +asynchronous communication between threads. +Often you need to communicate between different threads. In general +it's safer not to do this by shared memory, but by explicit message +passing. These messages only make sense asynchronously for +multi-threaded applications though, as a synchronous operation could as +well be done in the same thread. + + + +Asynchronous queues are an exception from most other GLib data +structures, as they can be used simultaneously from multiple threads +without explicit locking and they bring their own builtin reference +counting. This is because the nature of an asynchronous queue is, that +it will always be used by at least 2 concurrent threads. + + + +For using an asynchronous queue you first have to create one with +g_async_queue_new(). A newly created queue will get the reference +count 1. Whenever another thread is creating a new reference of (that +is pointer to) the queue, it has to increase the reference count +(using g_async_queue_ref()). Also, before removing this reference, the +reference count has to be decreased (using +g_async_queue_unref()). After that the queue might no longer exist so +you must not access it after that point. + + + +A thread, which wants to send a message to that queue simply calls +g_async_queue_push() to push the message to the queue. + + + +A thread, which is expecting messages from an asynchronous queue +simply calls g_async_queue_pop() for that queue. If no message is +available in the queue at that point, the thread is now put to sleep +until a message arrives. The message will be removed from the queue +and returned. The functions g_async_queue_try_pop() and +g_async_queue_timed_pop() can be used to only check for the presence +of messages or to only wait a certain time for messages respectively. + + +For almost every function there exist two variants, one that locks the +queue and one that doesn't. That way you can hold the queue lock +(acquire it with g_async_queue_lock() and release it with +g_async_queue_unlock()) over multiple queue accessing +instructions. This can be necessary to ensure the integrity of the +queue, but should only be used, when really necessary as it can make +your life harder if used unwisely. Normally you should only use the +locking function variants (those without the suffix _unlocking) @@ -16,153 +65,121 @@ Asynchronous Queues - +The #GAsyncQueue struct is an opaque data structure, which represents +an asynchronous queue. It should only be accessed through the +g_async_queue_* functions. - - @Returns: - - + - @queue: - - + - @queue: - - + - @queue: +@data: - - + - @queue: +@Returns: - - + - @queue: +@Returns: - - + - @queue: +@end_time: +@Returns: - - + - @queue: -@data: +@Returns: - - + - @queue: -@data: - - + - @queue: -@Returns: - - + - @queue: -@Returns: - - + - @queue: -@Returns: - - + - @queue: -@Returns: +@data: - - + - @queue: -@end_time: @Returns: - - + - @queue: -@end_time: @Returns: - - + - @queue: +@end_time: @Returns: - - @queue: @Returns: diff --git a/gasyncqueue.c b/gasyncqueue.c index 05c700f..126bb1d 100644 --- a/gasyncqueue.c +++ b/gasyncqueue.c @@ -1,7 +1,7 @@ /* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * - * GAsyncQueue: asyncronous queue implementation, based on Gqueue. + * GAsyncQueue: asynchronous queue implementation, based on Gqueue. * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe * * This library is free software; you can redistribute it and/or @@ -35,6 +35,13 @@ struct _GAsyncQueue guint ref_count; }; +/** + * g_async_queue_new: + * + * Creates a new asynchronous queue with the initial reference count of 1. + * + * Return value: the new #GAsyncQueue. + **/ GAsyncQueue* g_async_queue_new () { @@ -47,6 +54,12 @@ g_async_queue_new () return retval; } +/** + * g_async_queue_ref: + * @queue: a #GAsyncQueue. + * + * Increases the reference count of the asynchronous @queue by 1. + **/ void g_async_queue_ref (GAsyncQueue *queue) { @@ -58,6 +71,13 @@ g_async_queue_ref (GAsyncQueue *queue) g_mutex_unlock (queue->mutex); } +/** + * g_async_queue_ref_unlocked: + * @queue: a #GAsyncQueue. + * + * Increases the reference count of the asynchronous @queue by 1. This + * function must be called while holding the @queue's lock. + **/ void g_async_queue_ref_unlocked (GAsyncQueue *queue) { @@ -67,6 +87,19 @@ g_async_queue_ref_unlocked (GAsyncQueue *queue) queue->ref_count++; } +/** + * g_async_queue_unref_and_unlock: + * @queue: a #GAsyncQueue. + * + * Decreases the reference count of the asynchronous @queue by 1 and + * releases the lock. This function must be called while holding the + * @queue's lock. If the reference count went to 0, the @queue will be + * destroyed and the memory allocated will be freed. So you are not + * allowed to use the @queue afterwards, as it might have disappeared. + * The obvious asymmetry (it is not named + * g_async_queue_unref_unlocked) is because the queue can't be + * unlocked after dereffing it, as it might already have disappeared. + **/ void g_async_queue_unref_and_unlock (GAsyncQueue *queue) { @@ -89,6 +122,15 @@ g_async_queue_unref_and_unlock (GAsyncQueue *queue) } } +/** + * g_async_queue_unref: + * @queue: a #GAsyncQueue. + * + * Decreases the reference count of the asynchronous @queue by 1. If + * the reference count went to 0, the @queue will be destroyed and the + * memory allocated will be freed. So you are not allowed to use the + * @queue afterwards, as it might have disappeared. + **/ void g_async_queue_unref (GAsyncQueue *queue) { @@ -99,6 +141,14 @@ g_async_queue_unref (GAsyncQueue *queue) g_async_queue_unref_and_unlock (queue); } +/** + * g_async_queue_lock: + * @queue: a #GAsyncQueue. + * + * Acquire the @queue's lock. After that you can only call the + * g_async_queue_*_unlocked function variants on that + * @queue. Otherwise it will deadlock. + **/ void g_async_queue_lock (GAsyncQueue *queue) { @@ -108,6 +158,12 @@ g_async_queue_lock (GAsyncQueue *queue) g_mutex_lock (queue->mutex); } +/** + * g_async_queue_unlock: + * @queue: a #GAsyncQueue. + * + * Release the queue's lock. + **/ void g_async_queue_unlock (GAsyncQueue *queue) { @@ -117,6 +173,13 @@ g_async_queue_unlock (GAsyncQueue *queue) g_mutex_unlock (queue->mutex); } +/** + * g_async_queue_push: + * @queue: a #GAsyncQueue. + * @data: @data to push into the @queue. + * + * Push the @data into the @queue. @data must not be #NULL. + **/ void g_async_queue_push (GAsyncQueue* queue, gpointer data) { @@ -129,6 +192,14 @@ g_async_queue_push (GAsyncQueue* queue, gpointer data) g_mutex_unlock (queue->mutex); } +/** + * g_async_queue_push_unlocked: + * @queue: a #GAsyncQueue. + * @data: @data to push into the @queue. + * + * Push the @data into the @queue. @data must not be #NULL. This + * function must be called while holding the @queue's lock. + **/ void g_async_queue_push_unlocked (GAsyncQueue* queue, gpointer data) { @@ -176,6 +247,15 @@ g_async_queue_pop_intern_unlocked (GAsyncQueue* queue, gboolean try, return retval; } +/** + * g_async_queue_pop: + * @queue: a #GAsyncQueue. + * + * Pop data from the @queue. This function blocks until data become + * available. + * + * Return value: data from the queue. + **/ gpointer g_async_queue_pop (GAsyncQueue* queue) { @@ -191,6 +271,16 @@ g_async_queue_pop (GAsyncQueue* queue) return retval; } +/** + * g_async_queue_pop_unlocked: + * @queue: a #GAsyncQueue. + * + * Pop data from the @queue. This function blocks until data become + * available. This function must be called while holding the @queue's + * lock. + * + * Return value: data from the queue. + **/ gpointer g_async_queue_pop_unlocked (GAsyncQueue* queue) { @@ -200,6 +290,16 @@ g_async_queue_pop_unlocked (GAsyncQueue* queue) return g_async_queue_pop_intern_unlocked (queue, FALSE, NULL); } +/** + * g_async_queue_try_pop: + * @queue: a #GAsyncQueue. + * + * Try to pop data from the @queue. If no data is available, #NULL is + * returned. + * + * Return value: data from the queue or #NULL, when no data is + * available immediately. + **/ gpointer g_async_queue_try_pop (GAsyncQueue* queue) { @@ -215,6 +315,17 @@ g_async_queue_try_pop (GAsyncQueue* queue) return retval; } +/** + * g_async_queue_try_pop_unlocked: + * @queue: a #GAsyncQueue. + * + * Try to pop data from the @queue. If no data is available, #NULL is + * returned. This function must be called while holding the @queue's + * lock. + * + * Return value: data from the queue or #NULL, when no data is + * available immediately. + **/ gpointer g_async_queue_try_pop_unlocked (GAsyncQueue* queue) { @@ -224,6 +335,17 @@ g_async_queue_try_pop_unlocked (GAsyncQueue* queue) return g_async_queue_pop_intern_unlocked (queue, TRUE, NULL); } +/** + * g_async_queue_timed_pop: + * @queue: a #GAsyncQueue. + * @end_time: a #GTimeVal, determining the final time. + * + * Pop data from the @queue. If no data is received before @end_time, + * #NULL is returned. + * + * Return value: data from the queue or #NULL, when no data is + * received before @end_time. + **/ gpointer g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time) { @@ -239,6 +361,18 @@ g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time) return retval; } +/** + * g_async_queue_timed_pop_unlocked: + * @queue: a #GAsyncQueue. + * @end_time: a #GTimeVal, determining the final time. + * + * Pop data from the @queue. If no data is received before @end_time, + * #NULL is returned. This function must be called while holding the + * @queue's lock. + * + * Return value: data from the queue or #NULL, when no data is + * received before @end_time. + **/ gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time) { @@ -248,17 +382,22 @@ g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time) return g_async_queue_pop_intern_unlocked (queue, FALSE, end_time); } +/** + * g_async_queue_length: + * @queue: a #GAsyncQueue. + * + * Returns the length of the queue, negative values mean waiting + * threads, positive values mean available entries in the + * @queue. Actually this function returns the number of data items in + * the queue minus the number of waiting threads. Thus a return value + * of 0 could mean 'n' entries in the queue and 'n' thread waiting. + * That can happen due to locking of the queue or due to + * scheduling. + * + * Return value: the length of the @queue. + **/ gint -g_async_queue_length_unlocked (GAsyncQueue* queue) -{ - g_return_val_if_fail (queue, 0); - g_return_val_if_fail (queue->ref_count > 0, 0); - - return queue->queue->length - queue->waiting_threads; -} - -gint -g_async_queue_length(GAsyncQueue* queue) +g_async_queue_length (GAsyncQueue* queue) { glong retval; @@ -272,3 +411,27 @@ g_async_queue_length(GAsyncQueue* queue) return retval; } +/** + * g_async_queue_length_unlocked: + * @queue: a #GAsyncQueue. + * + * Returns the length of the queue, negative values mean waiting + * threads, positive values mean available entries in the + * @queue. Actually this function returns the number of data items in + * the queue minus the number of waiting threads. Thus a return value + * of 0 could mean 'n' entries in the queue and 'n' thread waiting. + * That can happen due to locking of the queue or due to + * scheduling. This function must be called while holding the @queue's + * lock. + * + * Return value: the length of the @queue. + **/ +gint +g_async_queue_length_unlocked (GAsyncQueue* queue) +{ + g_return_val_if_fail (queue, 0); + g_return_val_if_fail (queue->ref_count > 0, 0); + + return queue->queue->length - queue->waiting_threads; +} + diff --git a/glib/gasyncqueue.c b/glib/gasyncqueue.c index 05c700f..126bb1d 100644 --- a/glib/gasyncqueue.c +++ b/glib/gasyncqueue.c @@ -1,7 +1,7 @@ /* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * - * GAsyncQueue: asyncronous queue implementation, based on Gqueue. + * GAsyncQueue: asynchronous queue implementation, based on Gqueue. * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe * * This library is free software; you can redistribute it and/or @@ -35,6 +35,13 @@ struct _GAsyncQueue guint ref_count; }; +/** + * g_async_queue_new: + * + * Creates a new asynchronous queue with the initial reference count of 1. + * + * Return value: the new #GAsyncQueue. + **/ GAsyncQueue* g_async_queue_new () { @@ -47,6 +54,12 @@ g_async_queue_new () return retval; } +/** + * g_async_queue_ref: + * @queue: a #GAsyncQueue. + * + * Increases the reference count of the asynchronous @queue by 1. + **/ void g_async_queue_ref (GAsyncQueue *queue) { @@ -58,6 +71,13 @@ g_async_queue_ref (GAsyncQueue *queue) g_mutex_unlock (queue->mutex); } +/** + * g_async_queue_ref_unlocked: + * @queue: a #GAsyncQueue. + * + * Increases the reference count of the asynchronous @queue by 1. This + * function must be called while holding the @queue's lock. + **/ void g_async_queue_ref_unlocked (GAsyncQueue *queue) { @@ -67,6 +87,19 @@ g_async_queue_ref_unlocked (GAsyncQueue *queue) queue->ref_count++; } +/** + * g_async_queue_unref_and_unlock: + * @queue: a #GAsyncQueue. + * + * Decreases the reference count of the asynchronous @queue by 1 and + * releases the lock. This function must be called while holding the + * @queue's lock. If the reference count went to 0, the @queue will be + * destroyed and the memory allocated will be freed. So you are not + * allowed to use the @queue afterwards, as it might have disappeared. + * The obvious asymmetry (it is not named + * g_async_queue_unref_unlocked) is because the queue can't be + * unlocked after dereffing it, as it might already have disappeared. + **/ void g_async_queue_unref_and_unlock (GAsyncQueue *queue) { @@ -89,6 +122,15 @@ g_async_queue_unref_and_unlock (GAsyncQueue *queue) } } +/** + * g_async_queue_unref: + * @queue: a #GAsyncQueue. + * + * Decreases the reference count of the asynchronous @queue by 1. If + * the reference count went to 0, the @queue will be destroyed and the + * memory allocated will be freed. So you are not allowed to use the + * @queue afterwards, as it might have disappeared. + **/ void g_async_queue_unref (GAsyncQueue *queue) { @@ -99,6 +141,14 @@ g_async_queue_unref (GAsyncQueue *queue) g_async_queue_unref_and_unlock (queue); } +/** + * g_async_queue_lock: + * @queue: a #GAsyncQueue. + * + * Acquire the @queue's lock. After that you can only call the + * g_async_queue_*_unlocked function variants on that + * @queue. Otherwise it will deadlock. + **/ void g_async_queue_lock (GAsyncQueue *queue) { @@ -108,6 +158,12 @@ g_async_queue_lock (GAsyncQueue *queue) g_mutex_lock (queue->mutex); } +/** + * g_async_queue_unlock: + * @queue: a #GAsyncQueue. + * + * Release the queue's lock. + **/ void g_async_queue_unlock (GAsyncQueue *queue) { @@ -117,6 +173,13 @@ g_async_queue_unlock (GAsyncQueue *queue) g_mutex_unlock (queue->mutex); } +/** + * g_async_queue_push: + * @queue: a #GAsyncQueue. + * @data: @data to push into the @queue. + * + * Push the @data into the @queue. @data must not be #NULL. + **/ void g_async_queue_push (GAsyncQueue* queue, gpointer data) { @@ -129,6 +192,14 @@ g_async_queue_push (GAsyncQueue* queue, gpointer data) g_mutex_unlock (queue->mutex); } +/** + * g_async_queue_push_unlocked: + * @queue: a #GAsyncQueue. + * @data: @data to push into the @queue. + * + * Push the @data into the @queue. @data must not be #NULL. This + * function must be called while holding the @queue's lock. + **/ void g_async_queue_push_unlocked (GAsyncQueue* queue, gpointer data) { @@ -176,6 +247,15 @@ g_async_queue_pop_intern_unlocked (GAsyncQueue* queue, gboolean try, return retval; } +/** + * g_async_queue_pop: + * @queue: a #GAsyncQueue. + * + * Pop data from the @queue. This function blocks until data become + * available. + * + * Return value: data from the queue. + **/ gpointer g_async_queue_pop (GAsyncQueue* queue) { @@ -191,6 +271,16 @@ g_async_queue_pop (GAsyncQueue* queue) return retval; } +/** + * g_async_queue_pop_unlocked: + * @queue: a #GAsyncQueue. + * + * Pop data from the @queue. This function blocks until data become + * available. This function must be called while holding the @queue's + * lock. + * + * Return value: data from the queue. + **/ gpointer g_async_queue_pop_unlocked (GAsyncQueue* queue) { @@ -200,6 +290,16 @@ g_async_queue_pop_unlocked (GAsyncQueue* queue) return g_async_queue_pop_intern_unlocked (queue, FALSE, NULL); } +/** + * g_async_queue_try_pop: + * @queue: a #GAsyncQueue. + * + * Try to pop data from the @queue. If no data is available, #NULL is + * returned. + * + * Return value: data from the queue or #NULL, when no data is + * available immediately. + **/ gpointer g_async_queue_try_pop (GAsyncQueue* queue) { @@ -215,6 +315,17 @@ g_async_queue_try_pop (GAsyncQueue* queue) return retval; } +/** + * g_async_queue_try_pop_unlocked: + * @queue: a #GAsyncQueue. + * + * Try to pop data from the @queue. If no data is available, #NULL is + * returned. This function must be called while holding the @queue's + * lock. + * + * Return value: data from the queue or #NULL, when no data is + * available immediately. + **/ gpointer g_async_queue_try_pop_unlocked (GAsyncQueue* queue) { @@ -224,6 +335,17 @@ g_async_queue_try_pop_unlocked (GAsyncQueue* queue) return g_async_queue_pop_intern_unlocked (queue, TRUE, NULL); } +/** + * g_async_queue_timed_pop: + * @queue: a #GAsyncQueue. + * @end_time: a #GTimeVal, determining the final time. + * + * Pop data from the @queue. If no data is received before @end_time, + * #NULL is returned. + * + * Return value: data from the queue or #NULL, when no data is + * received before @end_time. + **/ gpointer g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time) { @@ -239,6 +361,18 @@ g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time) return retval; } +/** + * g_async_queue_timed_pop_unlocked: + * @queue: a #GAsyncQueue. + * @end_time: a #GTimeVal, determining the final time. + * + * Pop data from the @queue. If no data is received before @end_time, + * #NULL is returned. This function must be called while holding the + * @queue's lock. + * + * Return value: data from the queue or #NULL, when no data is + * received before @end_time. + **/ gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time) { @@ -248,17 +382,22 @@ g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time) return g_async_queue_pop_intern_unlocked (queue, FALSE, end_time); } +/** + * g_async_queue_length: + * @queue: a #GAsyncQueue. + * + * Returns the length of the queue, negative values mean waiting + * threads, positive values mean available entries in the + * @queue. Actually this function returns the number of data items in + * the queue minus the number of waiting threads. Thus a return value + * of 0 could mean 'n' entries in the queue and 'n' thread waiting. + * That can happen due to locking of the queue or due to + * scheduling. + * + * Return value: the length of the @queue. + **/ gint -g_async_queue_length_unlocked (GAsyncQueue* queue) -{ - g_return_val_if_fail (queue, 0); - g_return_val_if_fail (queue->ref_count > 0, 0); - - return queue->queue->length - queue->waiting_threads; -} - -gint -g_async_queue_length(GAsyncQueue* queue) +g_async_queue_length (GAsyncQueue* queue) { glong retval; @@ -272,3 +411,27 @@ g_async_queue_length(GAsyncQueue* queue) return retval; } +/** + * g_async_queue_length_unlocked: + * @queue: a #GAsyncQueue. + * + * Returns the length of the queue, negative values mean waiting + * threads, positive values mean available entries in the + * @queue. Actually this function returns the number of data items in + * the queue minus the number of waiting threads. Thus a return value + * of 0 could mean 'n' entries in the queue and 'n' thread waiting. + * That can happen due to locking of the queue or due to + * scheduling. This function must be called while holding the @queue's + * lock. + * + * Return value: the length of the @queue. + **/ +gint +g_async_queue_length_unlocked (GAsyncQueue* queue) +{ + g_return_val_if_fail (queue, 0); + g_return_val_if_fail (queue->ref_count > 0, 0); + + return queue->queue->length - queue->waiting_threads; +} + -- 2.7.4