summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2017-07-03 13:30:05 (GMT)
committersebres <sebres@users.sourceforge.net>2017-07-03 13:30:05 (GMT)
commit345817796217f5d895ed8bbd46a95bbbea799404 (patch)
treed2782538a1287b08c2d8bfad8a4becdb27e60955
parent96076219018ba504254a342c4490fc787bb0ceae (diff)
downloadtcl-345817796217f5d895ed8bbd46a95bbbea799404.zip
tcl-345817796217f5d895ed8bbd46a95bbbea799404.tar.gz
tcl-345817796217f5d895ed8bbd46a95bbbea799404.tar.bz2
amend with review
-rw-r--r--generic/tclTimer.c69
-rw-r--r--tests/event.test6
2 files changed, 56 insertions, 19 deletions
diff --git a/generic/tclTimer.c b/generic/tclTimer.c
index aad8ee3..a97c73a 100644
--- a/generic/tclTimer.c
+++ b/generic/tclTimer.c
@@ -285,6 +285,9 @@ TimerExitProc(
while ((tsdPtr->promptTail) != NULL) {
TclDeleteTimerEntry(tsdPtr->promptTail);
}
+ while ((tsdPtr->relTimerTail) != NULL) {
+ TclDeleteTimerEntry(tsdPtr->relTimerTail);
+ }
while ((tsdPtr->absTimerTail) != NULL) {
TclDeleteTimerEntry(tsdPtr->absTimerTail);
}
@@ -334,7 +337,7 @@ Tcl_CreateTimerHandler(
entryPtr = TclpCreateTimerHandlerEx(usec, proc, NULL, 0, 0);
if (entryPtr == NULL) {
- return NULL;
+ return NULL;
}
entryPtr->clientData = clientData;
@@ -412,15 +415,19 @@ TclpCreateTimerHandlerEx(
* end-time = base + relative event-time, which corresponds
* original end-time.
*/
- Tcl_WideInt diff = TclpGetLastTimeJump(&tsdPtr->knownTimeJumpEpoch);
- if (diff != 0) { /* jump recognized */
- tsdPtr->relTimerBase += diff; /* shift the base of relative events*/
+ Tcl_WideInt diff;
+ if ( (diff = TclpGetLastTimeJump(&tsdPtr->knownTimeJumpEpoch)) != 0
+ || (diff = (tsdPtr->knownTime - now)) < 0
+ ) { /* jump recognized */
+ tsdPtr->relTimerBase += diff; /* shift the base of relative events */
}
usec += now - tsdPtr->relTimerBase;
} else {
- tsdPtr->knownTime = tsdPtr->relTimerBase = now;
+ /* first event here - initial values (base/epoch) */
+ tsdPtr->relTimerBase = now;
tsdPtr->knownTimeJumpEpoch = TclpGetLastTimeJumpEpoch();
}
+ tsdPtr->knownTime = now;
}
timerPtr->time = usec;
@@ -504,7 +511,7 @@ TclCreateAbsoluteTimerHandler(
entryPtr = TclpCreateTimerHandlerEx(usec, proc, NULL, 0, TCL_ABSTMR_EVENT);
if (entryPtr == NULL) {
- return NULL;
+ return NULL;
}
entryPtr->clientData = clientData;
@@ -550,7 +557,7 @@ TclCreateRelativeTimerHandler(
entryPtr = TclpCreateTimerHandlerEx(usec, proc, NULL, 0, TCL_ABSTMR_EVENT);
if (entryPtr == NULL) {
- return NULL;
+ return NULL;
}
entryPtr->clientData = clientData;
@@ -587,6 +594,18 @@ Tcl_DeleteTimerHandler(
return;
}
+ for (entryPtr = tsdPtr->relTimerTail;
+ entryPtr != NULL;
+ entryPtr = entryPtr->prevPtr
+ ) {
+ if (TimerEntry2TimerHandler(entryPtr)->token != token) {
+ continue;
+ }
+
+ TclDeleteTimerEntry(entryPtr);
+ return;
+ }
+
for (entryPtr = tsdPtr->absTimerTail;
entryPtr != NULL;
entryPtr = entryPtr->prevPtr
@@ -622,8 +641,7 @@ Tcl_DeleteTimerHandler(
void
TclDeleteTimerEntry(
TimerEntry *entryPtr) /* Result previously returned by */
- /* TclCreateRelativeTimerHandlerEx, TclCreateAbsoluteTimerHandlerEx
- * or TclCreateTimerEntryEx. */
+ /* TclCreateTimerHandlerEx or TclCreateTimerEntryEx. */
{
ThreadSpecificData *tsdPtr;
@@ -642,10 +660,10 @@ TclDeleteTimerEntry(
} else {
/* timer event-handler */
tsdPtr->timerListEpoch++; /* signal-timer list was changed */
- if (entryPtr->flags & TCL_ABSTMR_EVENT) {
- TclSpliceOutEx(entryPtr, tsdPtr->absTimerList, tsdPtr->absTimerTail);
- } else {
+ if (!(entryPtr->flags & TCL_ABSTMR_EVENT)) {
TclSpliceOutEx(entryPtr, tsdPtr->relTimerList, tsdPtr->relTimerTail);
+ } else {
+ TclSpliceOutEx(entryPtr, tsdPtr->absTimerList, tsdPtr->absTimerTail);
}
}
@@ -662,6 +680,24 @@ TclDeleteTimerEntry(
}
}
+/*
+ *--------------------------------------------------------------
+ *
+ * TimerGetFirstTime --
+ *
+ * Find the execution time of first relative or absolute timer starting
+ * from given heads.
+ *
+ * Results:
+ * A wide integer representing the due time (as microseconds) of first
+ * timer event to execute.
+ *
+ * Side effects:
+ * If time-jump recognized, may adjust the base for relative timers.
+ *
+ *--------------------------------------------------------------
+ */
+
static Tcl_WideInt
TimerGetFirstTime(
ThreadSpecificData *tsdPtr,
@@ -673,10 +709,11 @@ TimerGetFirstTime(
Tcl_WideInt firstTime = -0x7FFFFFFFFFFFFFFFL;
/*
- * Consider time-jump back - if time jumped forwards, nothing to be done,
- * because event will be executed early as specified. But for backwards
- * jumps we should adjust relative base to avoid too long waiting for
- * relative events.
+ * Consider time-jump (especially back) - if the time jumped forwards (and
+ * it recognized) the base can be shifted, but not badly needed, because
+ * event will be nevertheless executed early as specified. But for backwards
+ * jumps it is very important and we should adjust relative base to avoid
+ * too long waiting for relative events.
*/
if (relTimerList) {
Tcl_WideInt diff;
diff --git a/tests/event.test b/tests/event.test
index d2dd2fc..f943f23 100644
--- a/tests/event.test
+++ b/tests/event.test
@@ -529,9 +529,9 @@ test event-11.4.0 {vwait - interp limit precedence} {} {
$i limit time -seconds {} -milliseconds {}
lappend result 2. [catch {$i eval {vwait 0 x}} msg] $msg
- # limit should be exceeded: (wait infinite by -1)
+ # limit should be exceeded: (wait infinite)
$i limit time -milliseconds 0
- lappend result 3. [catch {$i eval {vwait -1 x}} msg] $msg
+ lappend result 3. [catch {$i eval {vwait x}} msg] $msg
# limit should be exceeded (wait too long - 1000ms):
$i limit time -milliseconds 0
lappend result 4. [catch {$i eval {vwait 1000 x}} msg] $msg
@@ -597,7 +597,7 @@ test event-11.4.1 {vwait with timeout} {} {
lappend z $x; # 0 {} - (x still empty)
vwait 200 x; # wait up-to 200ms
lappend z $x; # 0 {} {1 2}
- vwait -1 x; # infinite wait
+ vwait x; # infinite wait
lappend z $x; # 0 {} {1 2} {1 2 3}
foreach i [after info] {
after cancel $i