[glib/wip/source-api: 3/5] GSource: new API g_source_set_ready_time()



commit 4218810dd0c65c3e80c201b5eadb72d6a5b69212
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Aug 30 15:21:56 2011 -0400

    GSource: new API g_source_set_ready_time()
    
    Add an API to mark a GSource to automatically become ready at the
    specified monotonic time.

 docs/reference/glib/glib-sections.txt |    1 +
 glib/glib.symbols                     |    1 +
 glib/gmain.c                          |   66 ++++++++++++++++++++++++++++++++-
 glib/gmain.h                          |    4 ++
 4 files changed, 71 insertions(+), 1 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 10f7ab9..7dad224 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -536,6 +536,7 @@ GSourceFunc
 g_source_set_callback_indirect
 g_source_add_poll
 g_source_remove_poll
+g_source_set_ready_time
 g_source_add_child_source
 g_source_remove_child_source
 g_source_get_time
diff --git a/glib/glib.symbols b/glib/glib.symbols
index 3af1cfa..f7dfd6d 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -625,6 +625,7 @@ g_source_set_name
 g_source_set_name_by_id
 g_source_is_destroyed
 g_source_set_priority
+g_source_set_ready_time
 g_source_unref
 g_idle_add
 g_idle_add_full
diff --git a/glib/gmain.c b/glib/gmain.c
index a320763..1197eec 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -308,6 +308,8 @@ struct _GSourcePrivate
 {
   GSList *child_sources;
   GSource *parent_source;
+
+  gint64 ready_time;
 };
 
 #ifdef G_THREADS_ENABLED
@@ -833,6 +835,8 @@ g_source_new (GSourceFuncs *source_funcs,
 
   source->flags = G_HOOK_FLAG_ACTIVE;
 
+  source->priv->ready_time = -1;
+
   /* NULL/0 initialization for all other fields */
   
   return source;
@@ -2327,6 +2331,29 @@ g_source_is_destroyed (GSource *source)
   return SOURCE_DESTROYED (source);
 }
 
+/**
+ * g_source_set_ready_time:
+ * @source: a #GSource
+ * @ready_time: the monotonic time at which the source will be ready,
+ *               or -1
+ *
+ * Sets a #GSource to be dispatched when the given monotonic time is
+ * reached (or passed).
+ *
+ * If @ready_time is -1 then the wakeup is unset.
+ *
+ * Since: 2.30
+ **/
+void
+g_source_set_ready_time (GSource *source,
+                          gint64   ready_time)
+{
+  g_return_if_fail (source != NULL);
+  g_return_if_fail (source->ref_count > 0);
+
+  source->priv->ready_time = ready_time;
+}
+
 /* Temporarily remove all this source's file descriptors from the
  * poll(), so that if data comes available for one of the file descriptors
  * we don't continually spin in the poll()
@@ -2750,6 +2777,31 @@ g_main_context_prepare (GMainContext *context,
 	  LOCK_CONTEXT (context);
 	  context->in_check_or_prepare--;
 
+          if (result == FALSE && source->priv->ready_time != -1)
+            {
+              if (!context->time_is_fresh)
+                {
+                  context->time = g_get_monotonic_time ();
+                  context->time_is_fresh = TRUE;
+                }
+
+              if (source->priv->ready_time <= context->time)
+                {
+                  source_timeout = 0;
+                  result = TRUE;
+                }
+              else
+                {
+                  gint timeout;
+
+                  /* rounding down will lead to spinning, so always round up */
+                  timeout = (source->priv->ready_time - context->time + 999) / 1000;
+
+                  if (source_timeout < 0 || timeout < source_timeout)
+                    source_timeout = timeout;
+                }
+            }
+
 	  if (result)
 	    {
 	      GSource *ready_source = source;
@@ -2942,7 +2994,19 @@ g_main_context_check (GMainContext *context,
 	  
 	  LOCK_CONTEXT (context);
 	  context->in_check_or_prepare--;
-	  
+
+          if (result == FALSE && source->priv->ready_time != -1)
+            {
+              if (!context->time_is_fresh)
+                {
+                  context->time = g_get_monotonic_time ();
+                  context->time_is_fresh = TRUE;
+                }
+
+              if (source->priv->ready_time <= context->time)
+                result = TRUE;
+            }
+
 	  if (result)
 	    {
 	      GSource *ready_source = source;
diff --git a/glib/gmain.h b/glib/gmain.h
index d31b45f..212271d 100644
--- a/glib/gmain.h
+++ b/glib/gmain.h
@@ -364,6 +364,10 @@ void     g_source_set_funcs       (GSource        *source,
                                    GSourceFuncs   *funcs);
 gboolean g_source_is_destroyed    (GSource        *source);
 
+void     g_source_set_ready_time  (GSource        *source,
+                                   gint64          wakeup_time);
+
+
 void                 g_source_set_name       (GSource        *source,
                                               const char     *name);
 const char *         g_source_get_name       (GSource        *source);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]