boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate)
{
std::istringstream is(localDate);
is.imbue(std::locale(is.getloc(), new boost::local_time::local_time_input_facet(format.c_str())));
boost::posix_time::ptime pt;
is >> pt;
if (pt == boost::posix_time::ptime())
{
throw std::runtime_error("Parse error");
}
return pt;
}
This function should take a date and a format string and return boost::posix_time::ptime
.
E.g.: 2012:06:14 02:50:58
and %Y:%m:%d %H:%M:%S
.
However if I call it in a multithreaded program, sometimes the exception is thrown, although format
and localDate
are correct and parseable (I use the same date for every call).
I found something about std::stringstream
/std::locale
thread issues but nothing up-to-date (I am using gcc 4.6.3 64bit).
Here someone has the same problem:
Testing over the last few days using Valgrind/drd, I have found many parts of my code that cause problems. For example, when calling some boost date time conversion functions, I hit std::locale(), which is not threadsafe.
Updated code that gives no problems:
boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate)
{
std::istringstream is(localDate);
auto* facet = new boost::local_time::local_time_input_facet(format.c_str());
{
boost::unique_lock<boost::mutex> lock(globalLocaleMutex);
is.imbue(std::locale(is.getloc(), facet));
}
boost::posix_time::ptime pt;
is >> pt;
if (pt == boost::posix_time::ptime())
{
throw std::runtime_error("Parse error");
}
return pt;
}
But still: Why?
I see there is a call to local_time. I am not sure if the underlying code calls localtime or localtime_r. If it calls localtime, then it is not thread safe. I believe that localtime uses a static variable when it returns the result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With