* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
#include "gasyncqueue.h"
#include "gasyncqueueprivate.h"
+#include "gmain.h"
#include "gmem.h"
#include "gqueue.h"
#include "gtestutils.h"
+#include "gtimer.h"
#include "gthread.h"
#include "deprecated/gthread.h"
* 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
+ * g_async_queue_timeout_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 GAsyncQueue struct is an opaque data structure which represents
* an asynchronous queue. It should only be accessed through the
- * <function>g_async_queue_*</function> functions.
+ * g_async_queue_* functions.
*/
struct _GAsyncQueue
{
*
* Creates a new asynchronous queue.
*
- * Return value: a new #GAsyncQueue. Free with g_async_queue_unref()
+ * Returns: a new #GAsyncQueue. Free with g_async_queue_unref()
*/
GAsyncQueue *
g_async_queue_new (void)
* function that is used to free any remaining queue items when
* the queue is destroyed after the final unref.
*
- * Return value: a new #GAsyncQueue. Free with g_async_queue_unref()
+ * Returns: a new #GAsyncQueue. Free with g_async_queue_unref()
*
* Since: 2.16
*/
*
* Increases the reference count of the asynchronous @queue by 1.
*
- * @Deprecated: Since 2.8, reference counting is done atomically
+ * Deprecated: 2.8: Reference counting is done atomically.
* so g_async_queue_ref() can be used regardless of the @queue's
* lock.
*/
* the @queue's lock. If the reference count went to 0, the @queue
* will be destroyed and the memory allocated will be freed.
*
- * @Deprecated: Since 2.8, reference counting is done atomically
+ * Deprecated: 2.8: Reference counting is done atomically.
* so g_async_queue_unref() can be used regardless of the @queue's
* lock.
*/
* Call g_async_queue_unlock() to drop the lock again.
*
* While holding the lock, you can only call the
- * <function>g_async_queue_*_unlocked()</function> functions
- * on @queue. Otherwise, deadlock may occur.
+ * g_async_queue_*_unlocked() functions on @queue. Otherwise,
+ * deadlock may occur.
*/
void
g_async_queue_lock (GAsyncQueue *queue)
static gpointer
g_async_queue_pop_intern_unlocked (GAsyncQueue *queue,
gboolean wait,
- GTimeVal *end_time)
+ gint64 end_time)
{
gpointer retval;
queue->waiting_threads++;
while (!g_queue_peek_tail_link (&queue->queue))
{
- if (!g_cond_timed_wait (&queue->cond, &queue->mutex, end_time))
- break;
+ if (end_time == -1)
+ g_cond_wait (&queue->cond, &queue->mutex);
+ else
+ {
+ if (!g_cond_wait_until (&queue->cond, &queue->mutex, end_time))
+ break;
+ }
}
queue->waiting_threads--;
}
retval = g_queue_pop_tail (&queue->queue);
- g_assert (retval || !wait || end_time);
+ g_assert (retval || !wait || end_time > 0);
return retval;
}
* Pops data from the @queue. If @queue is empty, this function
* blocks until data becomes available.
*
- * Return value: data from the queue
+ * Returns: data from the queue
*/
gpointer
g_async_queue_pop (GAsyncQueue *queue)
g_return_val_if_fail (queue, NULL);
g_mutex_lock (&queue->mutex);
- retval = g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
+ retval = g_async_queue_pop_intern_unlocked (queue, TRUE, -1);
g_mutex_unlock (&queue->mutex);
return retval;
*
* This function must be called while holding the @queue's lock.
*
- * Return value: data from the queue.
+ * Returns: data from the queue.
*/
gpointer
g_async_queue_pop_unlocked (GAsyncQueue *queue)
{
g_return_val_if_fail (queue, NULL);
- return g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
+ return g_async_queue_pop_intern_unlocked (queue, TRUE, -1);
}
/**
* Tries 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
+ * Returns: data from the queue or %NULL, when no data is
* available immediately.
*/
gpointer
g_return_val_if_fail (queue, NULL);
g_mutex_lock (&queue->mutex);
- retval = g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
+ retval = g_async_queue_pop_intern_unlocked (queue, FALSE, -1);
g_mutex_unlock (&queue->mutex);
return retval;
*
* This function must be called while holding the @queue's lock.
*
- * Return value: data from the queue or %NULL, when no data is
+ * Returns: data from the queue or %NULL, when no data is
* available immediately.
*/
gpointer
{
g_return_val_if_fail (queue, NULL);
- return g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
+ return g_async_queue_pop_intern_unlocked (queue, FALSE, -1);
+}
+
+/**
+ * g_async_queue_timeout_pop:
+ * @queue: a #GAsyncQueue
+ * @timeout: the number of microseconds to wait
+ *
+ * Pops data from the @queue. If the queue is empty, blocks for
+ * @timeout microseconds, or until data becomes available.
+ *
+ * If no data is received before the timeout, %NULL is returned.
+ *
+ * Returns: data from the queue or %NULL, when no data is
+ * received before the timeout.
+ */
+gpointer
+g_async_queue_timeout_pop (GAsyncQueue *queue,
+ guint64 timeout)
+{
+ gint64 end_time = g_get_monotonic_time () + timeout;
+ gpointer retval;
+
+ g_mutex_lock (&queue->mutex);
+ retval = g_async_queue_pop_intern_unlocked (queue, TRUE, end_time);
+ g_mutex_unlock (&queue->mutex);
+
+ return retval;
+}
+
+/**
+ * g_async_queue_timeout_pop_unlocked:
+ * @queue: a #GAsyncQueue
+ * @timeout: the number of microseconds to wait
+ *
+ * Pops data from the @queue. If the queue is empty, blocks for
+ * @timeout microseconds, or until data becomes available.
+ *
+ * If no data is received before the timeout, %NULL is returned.
+ *
+ * This function must be called while holding the @queue's lock.
+ *
+ * Returns: data from the queue or %NULL, when no data is
+ * received before the timeout.
+ */
+gpointer
+g_async_queue_timeout_pop_unlocked (GAsyncQueue *queue,
+ guint64 timeout)
+{
+ gint64 end_time = g_get_monotonic_time () + timeout;
+
+ return g_async_queue_pop_intern_unlocked (queue, TRUE, end_time);
}
/**
* To easily calculate @end_time, a combination of g_get_current_time()
* and g_time_val_add() can be used.
*
- * Return value: data from the queue or %NULL, when no data is
+ * Returns: data from the queue or %NULL, when no data is
* received before @end_time.
+ *
+ * Deprecated: use g_async_queue_timeout_pop().
*/
gpointer
g_async_queue_timed_pop (GAsyncQueue *queue,
GTimeVal *end_time)
{
+ gint64 m_end_time;
gpointer retval;
g_return_val_if_fail (queue, NULL);
+ if (end_time != NULL)
+ {
+ m_end_time = g_get_monotonic_time () +
+ ((gint64) end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec - g_get_real_time ());
+ }
+ else
+ m_end_time = -1;
+
g_mutex_lock (&queue->mutex);
- retval = g_async_queue_pop_intern_unlocked (queue, TRUE, end_time);
+ retval = g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time);
g_mutex_unlock (&queue->mutex);
return retval;
*
* This function must be called while holding the @queue's lock.
*
- * Return value: data from the queue or %NULL, when no data is
+ * Returns: data from the queue or %NULL, when no data is
* received before @end_time.
+ *
+ * Deprecated: use g_async_queue_timeout_pop_unlocked().
*/
gpointer
g_async_queue_timed_pop_unlocked (GAsyncQueue *queue,
GTimeVal *end_time)
{
+ gint64 m_end_time;
+
g_return_val_if_fail (queue, NULL);
- return g_async_queue_pop_intern_unlocked (queue, TRUE, end_time);
+ if (end_time != NULL)
+ {
+ m_end_time = g_get_monotonic_time () +
+ ((gint64) end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec - g_get_real_time ());
+ }
+ else
+ m_end_time = -1;
+
+ return g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time);
}
/**
* in the queue and n threads waiting. This can happen due to locking
* of the queue or due to scheduling.
*
- * Return value: the length of the @queue
+ * Returns: the length of the @queue
*/
gint
g_async_queue_length (GAsyncQueue *queue)
*
* This function must be called while holding the @queue's lock.
*
- * Return value: the length of the @queue.
+ * Returns: the length of the @queue.
*/
gint
g_async_queue_length_unlocked (GAsyncQueue *queue)
*
* If you were sorting a list of priority numbers to make sure the
* lowest priority would be at the top of the queue, you could use:
- * |[
+ * |[<!-- language="C" -->
* gint32 id1;
* gint32 id2;
*