Boost logo

Boost Users :

Subject: [Boost-users] [posix_time] time_from_string Not Thread-Safe?
From: Hering Cheng (hering.cheng_at_[hidden])
Date: 2013-03-14 12:52:36


Hi,

If I invoke boost::posix_time::time_from_string() from multiple threads I
get a core dump:

#0 0x00000000006ded78 in std::_Rb_tree<std::string, std::pair<std::string
const, unsigned short>, std::_Select1st<std::pair<std::string const,
unsigned short> >, std::less<std::string>,
std::allocator<std::pair<std::string const, unsigned short> >
>::_M_insert_unique(std::pair<std::string const, unsigned short> const&)
[clone .constprop.93] ()
(gdb) where
#0 0x00000000006ded78 in std::_Rb_tree<std::string, std::pair<std::string
const, unsigned short>, std::_Select1st<std::pair<std::string const,
unsigned short> >, std::less<std::string>,
std::allocator<std::pair<std::string const, unsigned short> >
>::_M_insert_unique(std::pair<std::string const, unsigned short> const&)
[clone .constprop.93] ()
#1 0x00000000006df400 in boost::gregorian::greg_month::get_month_map_ptr()
()
#2 0x00007f0dfbc590cd in
boost::date_time::month_str_to_ushort<boost::gregorian::greg_month> (s=...)
at
/home/chenher/projects/cactus_strategies/cactus_includes/boost/date_time/date_parsing.hpp:67
#3 0x00007f0dfbc29115 in
boost::date_time::parse_date<boost::gregorian::date> (s=..., order_spec=0)
at
/home/chenher/projects/cactus_strategies/cactus_includes/boost/date_time/date_parsing.hpp:143
#4 0x00007f0dfbc7b96f in parse_delimited_time<boost::posix_time::ptime>
(s=..., sep=<optimized out>) at
/home/chenher/projects/cactus_strategies/cactus_includes/boost/date_time/time_parsing.hpp:175
#5 time_from_string (s=...) at
/home/chenher/boost/date_time/posix_time/time_parsers.hpp:31

Looking at *libs/date_time/src/gregorian/greg_month.cpp*:37, it is apparent
that the use of a static variable renders the *month_map *not thread-safe:

  greg_month::month_map_ptr_type greg_month::get_month_map_ptr()
  {
    static month_map_ptr_type month_map_ptr(new
greg_month::month_map_type());

    if(month_map_ptr->empty()) {
      std::string s("");
      for(unsigned short i = 1; i <= 12; ++i) {
        greg_month m(static_cast<month_enum>(i));
        s = m.as_long_string();
        s = date_time::convert_to_lower(s);
        month_map_ptr->insert(std::make_pair(s, i));
        s = m.as_short_string();
        s = date_time::convert_to_lower(s);
        month_map_ptr->insert(std::make_pair(s, i));
      }
    }
    return month_map_ptr;
  }

Is there any way around this? Is there a general initialization routine I
can call to get all such use of static initialized by a single thread?

Thanks.
Hering Cheng



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net