diff options
author | sebres <sebres@users.sourceforge.net> | 2017-07-03 13:32:24 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2017-07-03 13:32:24 (GMT) |
commit | b6086dc8f3a848a02491d01415b6f379ef0b1284 (patch) | |
tree | db5dbaca15cdb1244dbbf9b183342b64f023cd94 /generic/tclTimer.c | |
parent | 0a588d204138059ddc43ebceb74de18ccf9c7836 (diff) | |
download | tcl-b6086dc8f3a848a02491d01415b6f379ef0b1284.zip tcl-b6086dc8f3a848a02491d01415b6f379ef0b1284.tar.gz tcl-b6086dc8f3a848a02491d01415b6f379ef0b1284.tar.bz2 |
after at: added simple workaround for absolute timers/sleep ("after at real-time"): because we use monotonic time in all wait functions, so to avoid too long wait by the absolute timers (to be able to trigger it) if time jumped to the expected absolute time, just let block for maximal 1 second if absolute timers available.
test-cases: time-jumps (TIP #302) test covered now.
Note: on some platforms it is only possible if the user has corresponding privileges to change system date and time.
Ex.: sudo LD_LIBRARY_PATH=. ./tclsh ../tests/timer.test -match timer-20.*
Diffstat (limited to 'generic/tclTimer.c')
-rw-r--r-- | generic/tclTimer.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/generic/tclTimer.c b/generic/tclTimer.c index 074b61d..d22d326 100644 --- a/generic/tclTimer.c +++ b/generic/tclTimer.c @@ -943,9 +943,24 @@ TimerSetupProc( #endif if (timeOffs > 0) { - blockTime.sec = (long) (timeOffs / 1000000); - blockTime.usec = (unsigned long) (timeOffs % 1000000); - + blockTime.sec = 0; + if (timeOffs >= 1000000) { + /* + * Note we use monotonic time by all wait functions, so to + * avoid too long wait by the absolute timers (to be able + * to trigger it) if time jumped to the expected time, just + * let block for maximal 1s if absolute timers available. + */ + if (tsdPtr->absTimerList) { + /* we've some absolute timers - won't wait longer as 1s. */ + timeOffs = 1000000; + } + blockTime.sec = (long) (timeOffs / 1000000); + blockTime.usec = (unsigned long)(timeOffs % 1000000); + } else { + blockTime.sec = 0; + blockTime.usec = (unsigned long)timeOffs; + } } else { blockTime.sec = 0; blockTime.usec = 0; @@ -1792,6 +1807,14 @@ AfterDelay( } } diff = endTime - now; + if (absolute && diff >= 1000000) { + /* + * Note by absolute sleep we should avoid too long waits, to be + * able to process further if time jumped to the expected time, so + * just let wait maximal 1 second. + */ + diff = 1000000; + } if (iPtr->limit.timeEvent == NULL || diff < limOffs) { if (diff > 0) { TclpUSleep(diff); |