
From: Jeff Garland
On Tue, 8 Mar 2005 11:34:15 +0200, Yitzhak Sapir wrote
Boost date_time apparently has a thread safety problem in linux in that it calls localtime() in boost/date_time/time_clock.hpp and related functions rather than localtime_r() and related functions. This is even though BOOST_HAS_PTHREADS is defined by configure in user.hpp.
That's true -- date_time doesn't do anything to ensure thread safety. I'm a little reluctant to protect these functions since the user can determine better if they need to take the associated performance hit. Of course this needs to be documented, which it isn't now. Thoughts?
Ok, having investigated the problem a little more, I get the following.. The problem comes down to the fact that localtime/gmtime call tzset(), which in turn calls getenv("TZ"). This call isn't done in the _r versions which use pretty much the same code. getenv() appears to be not thread safe, but I'm not sure why. This does indicate, however, that probably the _r versions are a little quicker (because they don't call getenv()). Running localtime (no _r) in loops in four threads on a multi cpu machine resulted in no segmentation fault. Maybe something else is interfering with getenv() in unforseeable ways? boost is not the only one making these calls. log4cxx is another third party we use and it also makes these calls. It also calls wcsftime, a version of strftime, which appears to always call tzset()/getenv(). So, wcsftime/strftime appear to be not threadsafe either. For the record, we use libgcc 3.3.3 and glibc 3.2.3. The libgcc is a by product of compiling an equivalent gcc on all machines for distcc purposes, while the glibc is the version that was installed with the operating system. I am wondering if this version mismatch could be the cause of the problems, but it seems the getenv.c hasn't changed in glibc for 2 years. A link to an example posting about a problem that seems very similar: http://lists.gnu.org/archive/html/bug-glibc/2002-11/msg00092.html If it is to be documented and not fixed, it should probably be documented in a central place for all boost. (This is a good idea regardless). I think it should be fixed, given that the main difference is using a static buffer vs a stack allocated buffer and that the current version does more work (damage?) than the reentrant version. Yitzhak Sapir