From: Yitzhak Sapir (yitzhak.sapir_at_[hidden])
Date: 2005-03-08 13:18:53
> 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:
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk