[newlib-cygwin] Cygwin: timerfd: prepare for TFD_TIMER_CANCEL_ON_SET

Corinna Vinschen corinna@sourceware.org
Sat Jan 19 19:54:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e32d1510da0f943dc4631bce3d49d85d156f78bd

commit e32d1510da0f943dc4631bce3d49d85d156f78bd
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Sat Jan 19 20:53:38 2019 +0100

    Cygwin: timerfd: prepare for TFD_TIMER_CANCEL_ON_SET
    
    Also drop debugging sleep and make sure overrun count is positive.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler_timerfd.cc |  2 --
 winsup/cygwin/timerfd.cc          | 22 ++++++++++++++--------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc
index 8d30856..33829ed 100644
--- a/winsup/cygwin/fhandler_timerfd.cc
+++ b/winsup/cygwin/fhandler_timerfd.cc
@@ -322,8 +322,6 @@ extern "C" int
 timerfd_settime (int fd_in, int flags, const struct itimerspec *value,
 		 struct itimerspec *ovalue)
 {
-  /* TODO: There's no easy way to implement TFD_TIMER_CANCEL_ON_SET,
-     but we should at least accept the flag. */
   if ((flags & ~(TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)) != 0)
     {
       set_errno (EINVAL);
diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc
index 145f3a6..ae26004 100644
--- a/winsup/cygwin/timerfd.cc
+++ b/winsup/cygwin/timerfd.cc
@@ -36,6 +36,7 @@ timerfd_tracker::thread_func ()
 	}
 
       /* Inner loop: Timer expired?  If not, wait for it. */
+      /* TODO: TFD_TIMER_CANCEL_ON_SET */
       HANDLE expired[3] = { tfd_shared->timer (),
 			    tfd_shared->disarm_evt (),
 			    cancel_evt };
@@ -359,16 +360,21 @@ repeat:
 	{
 	  ret = read_and_reset_overrun_count ();
 	  leave_critical_section ();
-	  if (ret)
-	    break;
-	  /* A 0 overrun count indicates another read was quicker.
-	     Continue as if we didn't catch the expiry. */
-	  if (!nonblocking)
+	  switch (ret)
 	    {
-	      Sleep (100L);
-	      goto repeat;
+	    case -1:	/* TFD_TIMER_CANCEL_ON_SET */
+	      ret = -ECANCELED;
+	      break;
+	    case 0:	/* Another read was quicker. */
+	      if (!nonblocking)
+		goto repeat;
+	      ret = -EAGAIN;
+	      break;
+	    default:	/* Return (positive) overrun count. */
+	      if (ret < 0)
+		ret = INT64_MAX;
+	      break;
 	    }
-	  ret = -EAGAIN;
 	}
       break;
     case WAIT_OBJECT_0 + 1:	/* signal */



More information about the Cygwin-cvs mailing list