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