summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2019-01-20 22:18:17 +0100
committerCorinna Vinschen <corinna@vinschen.de>2019-01-20 22:18:17 +0100
commit597285ca58770f3c9495aa91fbf24129b01cf426 (patch)
tree12563bbf674b58d07e0000028b0f4ec97ce7f36b
parente32d1510da0f943dc4631bce3d49d85d156f78bd (diff)
downloadcygnal-597285ca58770f3c9495aa91fbf24129b01cf426.tar.gz
cygnal-597285ca58770f3c9495aa91fbf24129b01cf426.tar.bz2
cygnal-597285ca58770f3c9495aa91fbf24129b01cf426.zip
Cygwin: timerfd: fix read(2) running wild
- On systems with inexact realtime clock, the current timestamp may be fractionally smaller than the desired timestamp. This breaks the computation for incrementing overrun_count so overrun_count may end up as 0. Expiring the timer with an overrun_count of 0 is a no-go. Make sure we always increment overrun_count by at least one after timer expiry. - Do not expire the timer when another process deletes its timer_tracker. This, too, may result in a 0 overrun_count. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/timerfd.cc4
1 files changed, 3 insertions, 1 deletions
diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc
index ae26004a4..dbb63e676 100644
--- a/winsup/cygwin/timerfd.cc
+++ b/winsup/cygwin/timerfd.cc
@@ -69,6 +69,9 @@ timerfd_tracker::thread_func ()
LONG64 now = get_clock_now ();
LONG64 ts = get_exp_ts ();
+ /* Make concessions for unexact realtime clock */
+ if (ts > now)
+ ts = now - 1;
increment_overrun_count ((now - ts + get_interval () - 1)
/ get_interval ());
/* Set exp_ts to current timestamp. Make sure exp_ts ends up
@@ -251,7 +254,6 @@ timerfd_shared::dtor ()
{
return false;
}
- timer_expired ();
disarm_timer ();
NtClose (_timer);
NtClose (_arm_evt);