incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Liviu Nicoara <nikko...@hates.ms>
Subject Re: STDCXX-1056 [was: Re: STDCXX forks]
Date Mon, 17 Sep 2012 15:17:35 GMT
On 09/17/12 09:51, Stefan Teleman wrote:
> On Mon, Sep 17, 2012 at 8:46 AM, Liviu Nicoara <nikkoara@hates.ms> wrote:
>
>> In the meantime I would like to stress again that __rw_get_numpunct is
>> perfectly thread-safe and does not need extra locking for perfect
>> forwarding.
>
> So, by removing the test for
>
>            if (!(_C_flags & _RW::__rw_gr))
>
> (or any other bitmask for that matter), the functions which were
> thread-unsafe - and were exhibiting all the symptoms of a run-time
> race condition -, magically became thread-safe?
>
> I have looked *extensively* at the code in __rw_get_numpunct. It is
> inherently thread-unsafe.

I mean to say that no extra locking is necessary when the public interface forwards and no
caching is done.

In more detail: __rw_get_numpunct code is entered upon a call from the protected virtual interface.
It calls facet _C_data member function which either returns objects constructed from previously-initialized
POD data (in which case no locking is necessary), or it attempts to first initialize the facet
data from the STDCXX database.

If the latter, the execution goes in the facet data initialization code which is appropriately
synchronized, see this stack trace:

(gdb) bt
#0  __rw::__rw_facet::_C_get_data (this=0x6e10a0) at <srcdir>/stdcxx/branches/4.2.x/src/facet.cpp:179
#1  0x000000000043788b in __rw::__rw_facet::_C_data (this=0x6e10a0) at <srcdir>/stdcxx/branches/4.2.x/include/loc/_facet.h:194
#2  0x000000000044874f in __rw::__rw_get_numpunct (pfacet=0x6e10a0, flags=4) at <srcdir>/stdcxx/branches/4.2.x/src/punct.cpp:80
#3  0x0000000000449a14 in __rw::__rw_get_punct (pfacet=0x6e10a0, flags=4) at <srcdir>/stdcxx/branches/4.2.x/src/punct.cpp:578
#4  0x000000000041cecf in std::numpunct<char>::do_grouping (this=0x6e10a0) at <srcdir>/stdcxx/branches/4.2.x/include/loc/_numpunct.h:99
#5  0x000000000041bd31 in std::numpunct<char>::grouping (this=0x6e10a0) at <srcdir>/stdcxx/branches/4.2.x/include/loc/_numpunct.h:190
#6  0x00000000004036b8 in main (argc=2, argv=0x7fffffffe018) at <srcdir>/stdcxx/branches/4.2.x/tests/localization/s.cpp:29
(gdb)

When the above fails, the facet data has not been initialized, e.g., when there is no STDCXX
locale database, or the name of the locale does not refer to a locale in STDCXX database.
The __rw_get_numpunct function will attempt next to use libc and system locales, via the __rw_setlocale
class, which again is properly synchronized and the scope of that lock extends to cover the
facet data initialization. See this stack trace:

(gdb) bt
#0  __rw::__rw_setlocale::__rw_setlocale (this=0x7fffffffdd30, locname=0x6e112a "en_US.utf8",
cat=6, nothrow=0) at <srcdir>/stdcxx/branches/4.2.x/src/setlocale.cpp:84
#1  0x0000000000448974 in __rw::__rw_get_numpunct (pfacet=0x6e10a0, flags=4) at <srcdir>/stdcxx/branches/4.2.x/src/punct.cpp:134
#2  0x0000000000449a14 in __rw::__rw_get_punct (pfacet=0x6e10a0, flags=4) at <srcdir>/stdcxx/branches/4.2.x/src/punct.cpp:578
#3  0x000000000041cecf in std::numpunct<char>::do_grouping (this=0x6e10a0) at <srcdir>/stdcxx/branches/4.2.x/include/loc/_numpunct.h:99
#4  0x000000000041bd31 in std::numpunct<char>::grouping (this=0x6e10a0) at <srcdir>/stdcxx/branches/4.2.x/include/loc/_numpunct.h:190
#5  0x00000000004036b8 in main (argc=2, argv=0x7fffffffe018) at <srcdir>/stdcxx/branches/4.2.x/tests/localization/s.cpp:29

I hope you agree that this synchronization is sufficient for the facet initialization and
reading of facet data.

Thanks.

Liviu

Mime
View raw message