https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=597285ca58770f3c9495aa91fbf24129b01cf426
commit 597285ca58770f3c9495aa91fbf24129b01cf426 Author: Corinna Vinschen <[email protected]> Date: Sun Jan 20 22:18:17 2019 +0100 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 <[email protected]> Diff: --- winsup/cygwin/timerfd.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index ae26004..dbb63e6 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);
