From ac8bb107ca7d45115b1877f6ed9d25b16456b4b4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 May 2003 02:30:47 +0000 Subject: Add tests to detect and avoid division by zero in the windows precision timer calibration logic. --- ChangeLog | 5 +++++ win/tclWinTime.c | 24 ++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a7543f..71614d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-05-23 D. Richard Hipp + + * win/tclWinTime.c: Add tests to detect and avoid a division by zero + in the windows precision timer calibration logic. + 2003-05-23 Don Porter * generic/tclObj.c (tclCmdNameType): Converted internal rep diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 9953085..593ca55 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinTime.c,v 1.18 2003/05/18 19:48:27 kennykb Exp $ + * RCS: @(#) $Id: tclWinTime.c,v 1.19 2003/05/24 02:30:48 drh Exp $ */ #include "tclWinInt.h" @@ -348,7 +348,8 @@ Tcl_GetTime(timePtr) TclpInitUnlock(); } - if ( timeInfo.perfCounterAvailable ) { + if ( timeInfo.perfCounterAvailable + && timeInfo.curCounterFreq.QuadPart!=0 ) { /* * Query the performance counter and use it to calculate the @@ -449,7 +450,6 @@ StopCalibration( ClientData unused ) * * Results: * Returns a pointer to a static string, or NULL on failure. - * Return value is in UTF-8 encoding * * Side effects: * None. @@ -785,7 +785,7 @@ CalibrationThread( LPVOID arg ) /* Run the calibration once a second */ - for ( ; ; ) { + while (timeInfo.perfCounterAvailable) { /* If the exitEvent is set, break out of the loop. */ @@ -856,6 +856,22 @@ UpdateTimeEachSecond() EnterCriticalSection( &timeInfo.cs ); /* + * We devide by timeInfo.curCounterFreq.QuadPart in several places. + * That value should always be positive on a correctly functioning + * system. But it is good to be defensive about such matters. + * So if something goes wrong and the value does goes to zero, we + * clear the timeInfo.perfCounterAvailable in order to cause the + * calibration thread to shut itself down, then return without additional + * processing. + */ + + if( timeInfo.curCounterFreq.QuadPart==0 ){ + LeaveCriticalSection( &timeInfo.cs ); + timeInfo.perfCounterAvailable = 0; + return; + } + + /* * Several things may have gone wrong here that have to * be checked for. * (1) The performance counter may have jumped. -- cgit v0.12