Re: [Boost-bugs] [Boost C++ Libraries] #6320: creation of path from std::string on Windows (VC10) crashes (access error)

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #6320: creation of path from std::string on Windows (VC10) crashes (access error)
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-12-14 18:38:15


#6320: creation of path from std::string on Windows (VC10) crashes (access error)
-----------------------------------+----------------------------------------
  Reporter: aris.basic@… | Owner: bemandawes
      Type: Bugs | Status: reopened
 Milestone: To Be Determined | Component: filesystem
   Version: Boost 1.51.0 | Severity: Problem
Resolution: | Keywords:
-----------------------------------+----------------------------------------

Comment (by jacob.schloss@…):

 I agree the issue is still present, I am getting crashes due to invalid
 access inside the path conversion routines. As original poster says issue
 is that the initialization of static members is not threadsafe in all pre
 c++11 compilers. This seems to be compiler dependent, gcc seems to default
 to adding serialization code, but provides -fno-threadsafe-statics to
 disable, [http://stackoverflow.com/questions/10585928/is-static-init-
 thread-safe-with-vc2010 MSVC seems to not be]. I am currently using MSVC
 2010.

 Although this comment states that the local is thread local
 {{{
 // The path locale, which is global to the thread, can be changed by the
 // imbue() function. It is initialized to an implementation defined
 locale.
 }}}


 It looks like the same path object is shared between threads
 {{{
   std::locale& path_locale()
   {
     static std::locale loc(default_locale());
     return loc;
   }
 }}}

 Adding explicit one time initialization code to the shared local object
 with boost::call_once works for me.


 {{{
   void make_loc(std::locale& loc)
   {
           loc = default_locale();
   }

   std::locale& path_locale()
   {
     static std::locale loc;

     static boost::once_flag once;
     boost::call_once(once, boost::bind(&make_loc, boost::ref(loc)));

     return loc;
   }
 }}}


 {{{
   void make_wchar_t_codecvt_facet(const path::codecvt_type *& cvt)
   {
           cvt = &std::use_facet<std::codecvt<wchar_t, char,
 std::mbstate_t> >
                   (path_locale());
   }

   const path::codecvt_type *& path::wchar_t_codecvt_facet()
   {
    static const std::codecvt<wchar_t, char, std::mbstate_t> *
      facet;

    static boost::once_flag once;
    boost::call_once(once, boost::bind(&make_wchar_t_codecvt_facet,
 boost::ref(facet)));

    return facet;
   }
 }}}

 Another workaround that seemed to work is to do a path string operation on
 one thread in advance of multithread operations.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/6320#comment:4>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:11 UTC