From: <ch...@us...> - 2011-06-30 19:17:17
|
Revision: 2827 http://proteowizard.svn.sourceforge.net/proteowizard/?rev=2827&view=rev Author: chambm Date: 2011-06-30 19:17:10 +0000 (Thu, 30 Jun 2011) Log Message: ----------- - added a hack to work around Darwin's thread-safety issues with strtod (used by istream and optimized_lexical_cast.hpp); the hack will only fix the optimized_lexical_cast.hpp specializations, so istreams and normal lexical_cast is still unsafe Modified Paths: -------------- trunk/pwiz/pwiz/utility/misc/optimized_lexical_cast.hpp Modified: trunk/pwiz/pwiz/utility/misc/optimized_lexical_cast.hpp =================================================================== --- trunk/pwiz/pwiz/utility/misc/optimized_lexical_cast.hpp 2011-06-29 19:32:23 UTC (rev 2826) +++ trunk/pwiz/pwiz/utility/misc/optimized_lexical_cast.hpp 2011-06-30 19:17:10 UTC (rev 2827) @@ -29,6 +29,30 @@ #include <boost/lexical_cast.hpp> #include <boost/logic/tribool.hpp> + +// HACK: Darwin strtod isn't threadsafe so strtod_l must be used +#ifdef __APPLE__ +#include <xlocale.h> +#include "boost/utility/singleton.hpp" + +namespace { + +class ThreadSafeCLocale : public boost::singleton<ThreadSafeCLocale> +{ + public: + ThreadSafeCLocale(boost::restricted) : c_locale(::newlocale(LC_ALL_MASK, "C", 0)) {} + ~ThreadSafeCLocale() {::freelocale(c_locale);} + ::locale_t c_locale; +}; + +} // namespace +#define STRTOD(x, y) strtod_l((x), (y), ThreadSafeCLocale::instance->c_locale) + +#else // __APPLE__ +#define STRTOD(x, y) strtod((x), (y)) +#endif // __APPLE__ + + // optimized string->numeric conversions namespace boost { @@ -38,7 +62,7 @@ errno = 0; const char* stringToConvert = str.c_str(); const char* endOfConversion = stringToConvert; - float value = (float) strtod( stringToConvert, const_cast<char**>(&endOfConversion) ); + float value = (float) STRTOD( stringToConvert, const_cast<char**>(&endOfConversion) ); if( ( value == 0.0f && stringToConvert == endOfConversion ) || // error: conversion could not be performed errno != 0 ) // error: overflow or underflow throw bad_lexical_cast();//throw bad_lexical_cast( std::type_info( str ), std::type_info( value ) ); @@ -51,7 +75,7 @@ errno = 0; const char* stringToConvert = str.c_str(); const char* endOfConversion = stringToConvert; - double value = strtod( stringToConvert, const_cast<char**>(&endOfConversion) ); + double value = STRTOD( stringToConvert, const_cast<char**>(&endOfConversion) ); if( ( value == 0.0 && stringToConvert == endOfConversion ) || // error: conversion could not be performed errno != 0 ) // error: overflow or underflow throw bad_lexical_cast();//throw bad_lexical_cast( std::type_info( str ), std::type_info( value ) ); @@ -134,7 +158,7 @@ { errno = 0; const char* endOfConversion = str; - float value = (float) strtod( str, const_cast<char**>(&endOfConversion) ); + float value = (float) STRTOD( str, const_cast<char**>(&endOfConversion) ); if( ( value == 0.0f && str == endOfConversion ) || // error: conversion could not be performed errno != 0 ) // error: overflow or underflow throw bad_lexical_cast();//throw bad_lexical_cast( std::type_info( str ), std::type_info( value ) ); @@ -146,7 +170,7 @@ { errno = 0; const char* endOfConversion = str; - double value = strtod( str, const_cast<char**>(&endOfConversion) ); + double value = STRTOD( str, const_cast<char**>(&endOfConversion) ); if( ( value == 0.0 && str == endOfConversion ) || // error: conversion could not be performed errno != 0 ) // error: overflow or underflow throw bad_lexical_cast();//throw bad_lexical_cast( std::type_info( str ), std::type_info( value ) ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |