[glib/wip/monotonic] won't be using this.....



commit c9307c4e7b57d096d4030693d022b79154a3f846
Author: Ryan Lortie <desrt desrt ca>
Date:   Sat Oct 23 17:14:45 2010 +0200

    won't be using this.....

 configure.ac |    2 +-
 glib/gmain.c |  144 ++++++++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 121 insertions(+), 25 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index f17df56..2ad1e49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -955,7 +955,7 @@ AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strn
 AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link statvfs statfs utimes getgrgid getpwuid)
 AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getmntinfo)
 # Check for high-resolution sleep functions
-AC_CHECK_FUNCS(nanosleep nsleep)
+AC_CHECK_FUNCS(nanosleep nsleep ppoll)
 AC_CHECK_FUNCS(splice)
 
 AC_CHECK_HEADERS(crt_externs.h)
diff --git a/glib/gmain.c b/glib/gmain.c
index 9745daa..6429b1e 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -89,6 +89,10 @@
 #include <sys/wait.h>
 #endif
 
+#ifdef HAVE_PPOLL
+#include <sys/poll.h>
+#endif
+
 #include "gmain.h"
 
 #include "garray.h"
@@ -235,7 +239,11 @@ struct _GMainContext
   gint ref_count;
 
   GPtrArray *pending_dispatches;
-  gint timeout;			/* Timeout for current iteration */
+
+  /* Timeout for current iteration.  %NULL for infinite.
+   */
+  GTimeSpec timespec_storage;
+  GTimeSpec *timeout;
 
   guint next_id;
   GSource *source_list;
@@ -345,7 +353,7 @@ static void g_source_destroy_internal           (GSource      *source,
 						 GMainContext *context,
 						 gboolean      have_lock);
 static void g_main_context_poll                 (GMainContext *context,
-						 gint          timeout,
+						 GTimeSpec    *timeout,
 						 gint          priority,
 						 GPollFD      *fds,
 						 gint          n_fds);
@@ -2522,7 +2530,10 @@ g_main_context_prepare (GMainContext *context,
   
   /* Prepare all sources */
 
-  context->timeout = -1;
+  {
+    GTimeSpec max = { G_MAXLONG, 999999999 };
+    context->timeout = max;
+  }
   
   source = next_valid_source (context, NULL);
   while (source)
@@ -2560,12 +2571,28 @@ g_main_context_prepare (GMainContext *context,
 	{
 	  n_ready++;
 	  current_priority = source->priority;
-	  context->timeout = 0;
+          context->have_timeout = TRUE;
+	  context->timeout.tv_sec = 0;
+	  context->timeout.tv_nsec = 0;
 	}
       
       if (source_timeout >= 0)
 	{
-	  if (context->timeout < 0)
+          GTimeSpec source_timespec;
+
+	  if (context->have_timeout)
+            {
+              /* Already have a timeout, so take the minimum of the two.
+               */
+
+            }
+          else
+            {
+              /
+            }
+
+          
+          context->timeout < 0)
 	    context->timeout = source_timeout;
 	  else
 	    context->timeout = MIN (context->timeout, source_timeout);
@@ -2583,6 +2610,17 @@ g_main_context_prepare (GMainContext *context,
   return (n_ready > 0);
 }
 
+gint
+g_main_context_query_internal (GMainContext *context,
+		               gint          max_priority,
+                               GTimeSpec    *timeout,
+                               gboolean     *wait,
+		               GPollFD      *fds,
+		               gint          n_fds)
+{
+
+}
+
 /**
  * g_main_context_query:
  * @context: a #GMainContext
@@ -2797,7 +2835,7 @@ g_main_context_iterate (GMainContext *context,
 			GThread      *self)
 {
   gint max_priority;
-  gint timeout;
+  GTimeSpec timeout;
   gboolean some_ready;
   gint nfds, allocated_nfds;
   GPollFD *fds = NULL;
@@ -2855,9 +2893,19 @@ g_main_context_iterate (GMainContext *context,
 
   if (!block)
     timeout = 0;
-  
-  g_main_context_poll (context, timeout, max_priority, fds, nfds);
-  
+
+  if (timeout >= 0)
+    {
+      GTimeSpec ts;
+
+      ts.tv_sec = timeout / 1000;
+      ts.tv_nsec = 1000000 * (timeout % 1000);
+      g_main_context_poll (context, &ts, max_priority, fds, nfds);
+    }
+ 
+  else
+    g_main_context_poll (context, NULL, max_priority, fds, nfds);
+ 
   some_ready = g_main_context_check (context, max_priority, fds, nfds);
   
   if (dispatch)
@@ -3145,7 +3193,7 @@ g_main_loop_get_context (GMainLoop *loop)
 /* HOLDS: context's lock */
 static void
 g_main_context_poll (GMainContext *context,
-		     gint          timeout,
+		     GTimeSpec    *timeout,
 		     gint          priority,
 		     GPollFD      *fds,
 		     gint          n_fds)
@@ -3155,16 +3203,15 @@ g_main_context_poll (GMainContext *context,
   GPollRec *pollrec;
   gint i;
 #endif
-
   GPollFunc poll_func;
 
-  if (n_fds || timeout != 0)
+  if (n_fds || timeout != NULL)
     {
 #ifdef	G_MAIN_POLL_DEBUG
       if (_g_main_poll_debug)
 	{
-	  g_print ("polling context=%p n=%d timeout=%d\n",
-		   context, n_fds, timeout);
+	  g_print ("polling context=%p n=%d timeout=%d.%09l\n",
+		   context, n_fds, (int) timeout->tv_sec, timeout->tv_nsec);
 	  poll_timer = g_timer_new ();
 	}
 #endif
@@ -3172,26 +3219,75 @@ g_main_context_poll (GMainContext *context,
       LOCK_CONTEXT (context);
 
       poll_func = context->poll_func;
-      
+
       UNLOCK_CONTEXT (context);
-      if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR)
-	{
+
+#ifdef HAVE_PPOLL
+      if (poll_func == g_poll)
+        {
+          /* ppoll is Linux-specific and our GTimeSpec is ABI compatible
+           * with the one from Linux, but double-check before we blindly
+           * pointer cast because this could cause some *very* strange
+           * bugs.
+           *
+           * note: Compiler will optimise this away.
+           */
+          g_assert (sizeof (struct timespec) == sizeof (GTimeSpec));
+          g_assert (G_STRUCT_OFFSET (struct timespec, tv_sec) ==
+                    G_STRUCT_OFFSET (GTimeSpec, tv_sec));
+          g_assert (sizeof ((struct timespec *) NULL)->tv_sec ==
+                    sizeof timeout->tv_sec);
+          g_assert (G_STRUCT_OFFSET (struct timespec, tv_nsec) ==
+                    G_STRUCT_OFFSET (GTimeSpec, tv_nsec));
+          g_assert (sizeof ((struct timespec *) NULL)->tv_nsec ==
+                    sizeof timeout->tv_nsec);
+
+          if (ppoll ((struct pollfd *) fds, n_fds,
+                     (struct timespec *) timeout, NULL) < 0 && errno != EINTR)
+            g_warning ("ppoll(2) failed due to: %s.", g_strerror (errno));
+        }
+      else
+#endif
+        {
+          int msec;
+
+          if (timeout != NULL)
+            {
+              if (timeout->tv_sec < 2000000)
+                {
+                  g_assert_cmpint (timeout->tv_nsec, <, 1000000000);
+                  msec = timeout->tv_sec * 1000;
+                  msec += timeout->tv_nsec / 1000000;
+                }
+              else
+                /* It was requested to sleep for more than ~23 days.
+                 * That comes close to wrapping a gint, so just sleep
+                 * for 23 days and try again after that.
+                 */
+                msec = 2000000000;
+            }
+          else
+            msec = -1;
+
+          if ((*poll_func) (fds, n_fds, msec) < 0 && errno != EINTR)
+            {
 #ifndef G_OS_WIN32
-	  g_warning ("poll(2) failed due to: %s.",
-		     g_strerror (errno));
+              g_warning ("poll(2) failed due to: %s.",
+                         g_strerror (errno));
 #else
-	  /* If g_poll () returns -1, it has already called g_warning() */
+              /* If g_poll () returns -1, it has already called g_warning() */
 #endif
-	}
+            }
+        }
       
 #ifdef	G_MAIN_POLL_DEBUG
       if (_g_main_poll_debug)
 	{
 	  LOCK_CONTEXT (context);
 
-	  g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
+	  g_print ("g_main_poll(%d) timeout: %d.%09l - elapsed %12.10f seconds",
 		   n_fds,
-		   timeout,
+		   (int) timeout->tv_sec, timeout->tv_nsec,
 		   g_timer_elapsed (poll_timer, NULL));
 	  g_timer_destroy (poll_timer);
 	  pollrec = context->poll_records;
@@ -3229,7 +3325,7 @@ g_main_context_poll (GMainContext *context,
 	  UNLOCK_CONTEXT (context);
 	}
 #endif
-    } /* if (n_fds || timeout != 0) */
+    } /* if (n_fds || timeout != NULL) */
 }
 
 /**



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