summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/fhandler_timerfd.cc2
-rw-r--r--winsup/cygwin/timerfd.cc22
2 files changed, 14 insertions, 10 deletions
diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc
index 8d3085692..33829edac 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 145f3a665..ae26004a4 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 */