From d1e645da63404e176f053843c95d5e11b10511ed Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 13 Jul 2017 15:41:57 +0000 Subject: timer: fixed setup of the block-time to 0.0 by pending timer of new generation, example: tclsh -c "proc test {} {after 1000 test}; test; vwait infinite" --- generic/tclTimer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclTimer.c b/generic/tclTimer.c index d22d326..d4919f5 100644 --- a/generic/tclTimer.c +++ b/generic/tclTimer.c @@ -1208,7 +1208,6 @@ TclServiceTimerEvents(void) /* be sure that timer-list was not changed inside the proc call */ if (currentEpoch != tsdPtr->timerListEpoch) { /* timer-list was changed - stop processing */ - tsdPtr->timerPending++; break; } } -- cgit v0.12 From d08c41030e00d38de2ffbe8ff261d0a57b874eaf Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 13 Jul 2017 15:43:42 +0000 Subject: avoid busy wait if new short block-time will be set within service event-cycle (Tcl_DoOneEvent) produced in event-cycle without processing --- generic/tclNotify.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/generic/tclNotify.c b/generic/tclNotify.c index 28c3879..1bb21b4 100644 --- a/generic/tclNotify.c +++ b/generic/tclNotify.c @@ -1526,10 +1526,18 @@ Tcl_DoOneEvent( */ result = 0; - if (blockTimeWasSet) { + if ((flags & TCL_DONT_WAIT) || blockTimeWasSet) { break; } - } while ( !(flags & TCL_DONT_WAIT) ); + + /* + * Reset block time before continue event-cycle. + */ + if (tsdPtr->blockTimeServLev < tsdPtr->serviceLevel) { + tsdPtr->blockTimeSet = 0; + tsdPtr->blockTimeServLev = 0; + } + } while (1); done: /* @@ -1579,6 +1587,7 @@ Tcl_ServiceAll(void) * avoid recursive calls. */ + tsdPtr->serviceLevel++; tsdPtr->serviceMode = TCL_SERVICE_NONE; /* @@ -1595,23 +1604,29 @@ Tcl_ServiceAll(void) * so we can avoid multiple changes. */ + tsdPtr->inTraversal++; tsdPtr->blockTimeSet = 0; + tsdPtr->blockTimeServLev = 0; SetUpEventSources(tsdPtr, TCL_ALL_EVENTS); CheckEventSources(tsdPtr, TCL_ALL_EVENTS); - while (Tcl_ServiceEvent(0)) { + if (Tcl_ServiceEvent(0)) { + while (Tcl_ServiceEvent(0)) {}; result = 1; } if (TclServiceIdle()) { result = 1; } - if (!tsdPtr->blockTimeSet) { - Tcl_SetTimer(NULL); - } else { - Tcl_SetTimer(&tsdPtr->blockTime); + if (tsdPtr->inTraversal-- <= 1) { + if (!tsdPtr->blockTimeSet) { + Tcl_SetTimer(NULL); + } else { + Tcl_SetTimer(&tsdPtr->blockTime); + } } + tsdPtr->serviceLevel--; tsdPtr->serviceMode = TCL_SERVICE_ALL; return result; } -- cgit v0.12