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

commit e32d1510da0f943dc4631bce3d49d85d156f78bd
Author: Corinna Vinschen <[email protected]>
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 <[email protected]>

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 */

Reply via email to