From: VMware, Inc <> Date: Mon, 26 Apr 2010 18:40:14 +0000 (-0700) Subject: multi thread fix for evct and fcvt use in bsd printf X-Git-Tag: 2010.04.25-253928~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a29eb21e2c97054c477500f50cacbcdbf367014b;p=thirdparty%2Fopen-vm-tools.git multi thread fix for evct and fcvt use in bsd printf Can't use mxuser locks for this because they'll pull in lib/lock all over the place. On Windows use the thread-safe functions _ecvt_s and _fcvt_s instead of having to dynamically allocate a mutex. There are thread-safe versions for Linux, too, ecvt_r and fcvt_r, but they are not available on Mac. Since there was going to be a mutex in this code for Mac, might as well use it for Linux, too. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/string/bsd_output_shared.c b/open-vm-tools/lib/string/bsd_output_shared.c index 3616947c3..56bb804ac 100644 --- a/open-vm-tools/lib/string/bsd_output_shared.c +++ b/open-vm-tools/lib/string/bsd_output_shared.c @@ -52,16 +52,13 @@ #include #include #include +#ifndef _WIN32 +#include +#endif #include "vmware.h" #include "bsd_output_int.h" -#ifdef _WIN32 -#define strdup(string) _strdup(string) -#define fcvt(number, ndigits, decpt, sign) _fcvt(number, ndigits, decpt, sign) -#define ecvt(number, ndigits, decpt, sign) _ecvt(number, ndigits, decpt, sign) -#endif - #ifndef NO_FLOATING_POINT /* @@ -107,8 +104,13 @@ dtoa(double d, // IN char *str = NULL; int dec; +#ifndef _WIN32 + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + if (2 == mode) { + pthread_mutex_lock(&mutex); str = strdup(ecvt(d, prec, &dec, sign)); + pthread_mutex_unlock(&mutex); } else { ASSERT(3 == mode); @@ -128,24 +130,45 @@ dtoa(double d, // IN if (prec == 0) { size_t l; + pthread_mutex_lock(&mutex); str = strdup(fcvt(round(d), 1, &dec, sign)); - if (str == NULL) { - goto exit; - } - l = strlen(str); - ASSERT(l > 0); - l--; - ASSERT(str[l] == '0'); - str[l] = '\0'; - } else -#endif - - str = strdup(fcvt(d, prec, &dec, sign)); - -#ifdef _WIN32 + pthread_mutex_unlock(&mutex); + if (str) { + l = strlen(str); + ASSERT(l > 0); + l--; + ASSERT(str[l] == '0'); + str[l] = '\0'; + } + } else +#endif // __APPLE__ + { + pthread_mutex_lock(&mutex); + str = strdup(fcvt(d, prec, &dec, sign)); + pthread_mutex_unlock(&mutex); + } + } +#else // _WIN32 + if (2 == mode) { + str = malloc(_CVTBUFSIZE); + if (str) { + if (_ecvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) { + free(str); + str = NULL; + } + } + } else { + ASSERT(3 == mode); + str = malloc(_CVTBUFSIZE); + if (str) { + if (_fcvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) { + free(str); + str = NULL; + } + } /* * When the value is not zero but rounds to zero at prec digits, - * the Windows fcvt() sometimes return the empty string and + * the Windows fcvt() sometimes returns the empty string and * a negative dec that goes too far (as in -dec > prec). * For example, converting 0.001 with prec 1 results in * the empty string and dec -2. (See bug 253674.) @@ -159,26 +182,23 @@ dtoa(double d, // IN * for this bug. */ - if (*str == '\0' && dec < 0 && dec < -prec) { + if (str && *str == '\0' && dec < 0 && dec < -prec) { dec = -prec; } -#endif } +#endif // _WIN32 - if (!str) { - goto exit; - } + if (str) { + *strEnd = str + strlen(str); - *strEnd = str + strlen(str); + /* strip trailing zeroes */ + while ((*strEnd > str) && ('0' == *((*strEnd) - 1))) { + (*strEnd)--; + } - /* strip trailing zeroes */ - while ((*strEnd > str) && ('0' == *((*strEnd) - 1))) { - (*strEnd)--; + *expOut = dec; } - *expOut = dec; - - exit: return str; }