summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2005-07-27 18:23:58 (GMT)
committerdgp <dgp@users.sourceforge.net>2005-07-27 18:23:58 (GMT)
commit41ae541c110c5729d4467ce0c5c0a5bc9aa24d48 (patch)
tree7a802820f5119c7bdc8585cbd1db617cbd5f4e63 /generic
parente5c93914d5de3897143d17c46b6e4faf138db73c (diff)
downloadtcl-41ae541c110c5729d4467ce0c5c0a5bc9aa24d48.zip
tcl-41ae541c110c5729d4467ce0c5c0a5bc9aa24d48.tar.gz
tcl-41ae541c110c5729d4467ce0c5c0a5bc9aa24d48.tar.bz2
* generic/tclUtil.c: Converted the $::tcl_precision value to be
kept per-thread to prevent different threads from stomping on each others' formatting prescriptions. ***POTENTIAL INCOMPATIBILITY*** Multi-threaded programs that set the value of ::tcl_precision will now have to set it in each thread.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclUtil.c44
1 files changed, 14 insertions, 30 deletions
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 1031334..30cf775 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUtil.c,v 1.62 2005/07/24 22:56:44 dkf Exp $
+ * RCS: @(#) $Id: tclUtil.c,v 1.63 2005/07/27 18:24:02 dgp Exp $
*/
#include "tclInt.h"
@@ -72,16 +72,11 @@ static ProcessGlobalValue executableName = {0, 0, NULL, NULL, NULL, NULL, NULL};
#define BRACES_UNMATCHED 4
/*
- * The following values determine the precision used when converting
- * floating-point values to strings. This information is linked to all of the
- * tcl_precision variables in all interpreters via the function
- * TclPrecTraceProc.
+ * The following key is used by Tcl_PrintDouble and TclPrecTraceProc to
+ * access the precision to be used for double formatting.
*/
-static int precision = 0; /* Precision of floating point conversions, in
- * the range 0-17 inclusive. */
-
-TCL_DECLARE_MUTEX(precisionMutex)
+static Tcl_ThreadDataKey precisionKey;
/*
* Prototypes for functions defined later in this file.
@@ -1887,24 +1882,21 @@ Tcl_PrintDouble(interp, value, dst)
* at least TCL_DOUBLE_SPACE characters. */
{
char *p, c;
- int prec;
int exp;
int signum;
char buffer[TCL_DOUBLE_SPACE];
Tcl_UniChar ch;
- Tcl_MutexLock(&precisionMutex);
- prec = precision;
- Tcl_MutexUnlock(&precisionMutex);
+ int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int)sizeof(int));
/*
- * If prec == 0, then use TclDoubleDigits to develop a decimal significand
- * and exponent, then format it in E or F format as appropriate. If prec
- * != 0, use the native sprintf and then add a trailing ".0" if there is
- * no decimal point in the rep.
+ * If *precisionPtr == 0, then use TclDoubleDigits to develop a decimal
+ * significand and exponent, then format it in E or F format as
+ * appropriate. If *precisionPtr != 0, use the native sprintf and then
+ * add a trailing ".0" if there is no decimal point in the rep.
*/
- if ( prec == 0 ) {
+ if ( *precisionPtr == 0 ) {
/*
* Handle NaN.
*/
@@ -1935,7 +1927,6 @@ Tcl_PrintDouble(interp, value, dst)
if (signum) {
*dst++ = '-';
}
- prec = strlen(buffer);
p = buffer;
if (exp < -3 || exp > 17) {
/*
@@ -1989,7 +1980,7 @@ Tcl_PrintDouble(interp, value, dst)
* tcl_precision is supplied, pass it to the native sprintf.
*/
- sprintf(dst, "%.*g", prec, value);
+ sprintf(dst, "%.*g", *precisionPtr, value);
/*
* If the ASCII result looks like an integer, add ".0" so that it
@@ -2047,6 +2038,7 @@ TclPrecTraceProc(clientData, interp, name1, name2, flags)
{
Tcl_Obj* value;
int prec;
+ int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int)sizeof(int));
/*
* If the variable is unset, then recreate the trace.
@@ -2069,10 +2061,8 @@ TclPrecTraceProc(clientData, interp, name1, name2, flags)
if (flags & TCL_TRACE_READS) {
- Tcl_MutexLock(&precisionMutex);
- Tcl_SetVar2Ex(interp, name1, name2, Tcl_NewIntObj(precision),
+ Tcl_SetVar2Ex(interp, name1, name2, Tcl_NewIntObj(*precisionPtr),
flags & TCL_GLOBAL_ONLY);
- Tcl_MutexUnlock(&precisionMutex);
return (char *) NULL;
}
@@ -2083,10 +2073,6 @@ TclPrecTraceProc(clientData, interp, name1, name2, flags)
*/
if (Tcl_IsSafe(interp)) {
- Tcl_MutexLock(&precisionMutex);
- Tcl_SetVar2Ex(interp, name1, name2, Tcl_NewIntObj(precision),
- flags & TCL_GLOBAL_ONLY);
- Tcl_MutexUnlock(&precisionMutex);
return "can't modify precision from a safe interpreter";
}
value = Tcl_GetVar2Ex(interp, name1, name2, flags & TCL_GLOBAL_ONLY);
@@ -2095,9 +2081,7 @@ TclPrecTraceProc(clientData, interp, name1, name2, flags)
|| prec < 0 || prec > TCL_MAX_PREC) {
return "improper value for precision";
}
- Tcl_MutexLock(&precisionMutex);
- precision = prec;
- Tcl_MutexUnlock(&precisionMutex);
+ *precisionPtr = prec;
return (char *) NULL;
}