summaryrefslogtreecommitdiff
path: root/glib
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2012-02-08 08:26:36 -0500
committerDan Winship <danw@gnome.org>2012-02-13 09:09:08 -0500
commitdd553a2ba32cd8523e3097d34228c21b96a3f10c (patch)
treef325c5bea4f98f32938512c004db1bbfd713cf09 /glib
parent99af65a079e4d7c0c20960a6e68f83b3c56f6f20 (diff)
downloadglib-dd553a2ba32cd8523e3097d34228c21b96a3f10c.tar.gz
gasyncqueue: deprecate GTimeVal-based methods, add relative-delay ones
https://bugzilla.gnome.org/show_bug.cgi?id=669670
Diffstat (limited to 'glib')
-rw-r--r--glib/gasyncqueue.c105
-rw-r--r--glib/gasyncqueue.h15
-rw-r--r--glib/glib.symbols2
-rw-r--r--glib/gthreadpool.c16
4 files changed, 111 insertions, 27 deletions
diff --git a/glib/gasyncqueue.c b/glib/gasyncqueue.c
index 18c154cdc..195445e98 100644
--- a/glib/gasyncqueue.c
+++ b/glib/gasyncqueue.c
@@ -29,9 +29,11 @@
#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"
@@ -67,7 +69,7 @@
* 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
@@ -406,7 +408,7 @@ g_async_queue_push_sorted_unlocked (GAsyncQueue *queue,
static gpointer
g_async_queue_pop_intern_unlocked (GAsyncQueue *queue,
gboolean wait,
- GTimeVal *end_time)
+ gint64 end_time)
{
gpointer retval;
@@ -415,15 +417,20 @@ g_async_queue_pop_intern_unlocked (GAsyncQueue *queue,
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;
}
@@ -445,7 +452,7 @@ 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;
@@ -467,7 +474,7 @@ 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);
}
/**
@@ -488,7 +495,7 @@ g_async_queue_try_pop (GAsyncQueue *queue)
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;
@@ -511,7 +518,58 @@ g_async_queue_try_pop_unlocked (GAsyncQueue *queue)
{
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.
+ *
+ * Return value: 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
+ * @time: 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.
+ *
+ * Return value: 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);
}
/**
@@ -529,17 +587,29 @@ g_async_queue_try_pop_unlocked (GAsyncQueue *queue)
*
* Return value: 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 () +
+ (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;
@@ -562,14 +632,27 @@ g_async_queue_timed_pop (GAsyncQueue *queue,
*
* Return value: 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 () +
+ (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);
}
/**
diff --git a/glib/gasyncqueue.h b/glib/gasyncqueue.h
index e8fd0bfe6..f0d6d959a 100644
--- a/glib/gasyncqueue.h
+++ b/glib/gasyncqueue.h
@@ -66,10 +66,10 @@ gpointer g_async_queue_pop (GAsyncQueue *queue);
gpointer g_async_queue_pop_unlocked (GAsyncQueue *queue);
gpointer g_async_queue_try_pop (GAsyncQueue *queue);
gpointer g_async_queue_try_pop_unlocked (GAsyncQueue *queue);
-gpointer g_async_queue_timed_pop (GAsyncQueue *queue,
- GTimeVal *end_time);
-gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue *queue,
- GTimeVal *end_time);
+gpointer g_async_queue_timeout_pop (GAsyncQueue *queue,
+ guint64 timeout);
+gpointer g_async_queue_timeout_pop_unlocked (GAsyncQueue *queue,
+ guint64 timeout);
gint g_async_queue_length (GAsyncQueue *queue);
gint g_async_queue_length_unlocked (GAsyncQueue *queue);
void g_async_queue_sort (GAsyncQueue *queue,
@@ -79,6 +79,13 @@ void g_async_queue_sort_unlocked (GAsyncQueue *queue,
GCompareDataFunc func,
gpointer user_data);
+GLIB_DEPRECATED_FOR(g_async_queue_timeout_pop)
+gpointer g_async_queue_timed_pop (GAsyncQueue *queue,
+ GTimeVal *end_time);
+GLIB_DEPRECATED_FOR(g_async_queue_timeout_pop_unlocked)
+gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue *queue,
+ GTimeVal *end_time);
+
G_END_DECLS
#endif /* __G_ASYNCQUEUE_H__ */
diff --git a/glib/glib.symbols b/glib/glib.symbols
index d13420f39..6c2db0da6 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -80,6 +80,8 @@ g_async_queue_sort
g_async_queue_sort_unlocked
g_async_queue_timed_pop
g_async_queue_timed_pop_unlocked
+g_async_queue_timeout_pop
+g_async_queue_timeout_pop_unlocked
g_async_queue_try_pop
g_async_queue_try_pop_unlocked
g_async_queue_unlock
diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c
index b5e7dec82..de5b9de01 100644
--- a/glib/gthreadpool.c
+++ b/glib/gthreadpool.c
@@ -163,15 +163,11 @@ g_thread_pool_wait_for_new_pool (void)
else if (local_max_idle_time > 0)
{
/* If a maximal idle time is given, wait for the given time. */
- GTimeVal end_time;
-
- g_get_current_time (&end_time);
- g_time_val_add (&end_time, local_max_idle_time * 1000);
-
DEBUG_MSG (("thread %p waiting in global pool for %f seconds.",
g_thread_self (), local_max_idle_time / 1000.0));
- pool = g_async_queue_timed_pop (unused_thread_queue, &end_time);
+ pool = g_async_queue_timeout_pop (unused_thread_queue,
+ local_max_idle_time * 1000);
}
else
{
@@ -260,17 +256,13 @@ g_thread_pool_wait_for_new_task (GRealThreadPool *pool)
/* A thread will wait for new tasks for at most 1/2
* second before going to the global pool.
*/
- GTimeVal end_time;
-
- g_get_current_time (&end_time);
- g_time_val_add (&end_time, G_USEC_PER_SEC / 2); /* 1/2 second */
-
DEBUG_MSG (("thread %p in pool %p waits for up to a 1/2 second for task "
"(%d running, %d unprocessed).",
g_thread_self (), pool, pool->num_threads,
g_async_queue_length_unlocked (pool->queue)));
- task = g_async_queue_timed_pop_unlocked (pool->queue, &end_time);
+ task = g_async_queue_timeout_pop_unlocked (pool->queue,
+ G_USEC_PER_SEC / 2);
}
}
else