On 09/12/12 00:21, Stefan Teleman wrote:
On Tue, Sep 11, 2012 at 10:18 PM, Liviu Nicoara <nikko...@hates.ms> wrote:
AFAICT, there are two cases to consider:
1. Using STDCXX locale database initializes the __rw_punct_t data in the
first, properly synchronized pass through __rw_get_numpunct. All subsequent
calls use the __rw_punct_t data to construct returned objects.
2. Using the C library locales does the same in the first pass, via
setlocale and localeconv, but setlocale synchronization is via a per-process
lock. The facet data, once initialized is used just like above.
I probably missed this in the previous conversation, but did you detect a
race condition in the tests if the facets are simply forwarding to the
private virtual interface? I.e., did you detect that the facet
initialization code is unsafe? I think the facet __rw_punct_t data is safely
initialized in both cases, it's the caching that is done incorrectly.
I originally thought so too, but now I'm having doubts. :-) And I
haven't tracked it down with 100% accuracy yet. I saw today this
comment in src/facet.cpp, line 358:
// a per-process array of facet pointers sufficiently large
// to hold (pointers to) all standard facets for 8 locales
static __rw_facet* std_facet_buf [__rw_facet::_C_last_type * 8];
The localization code is cleverly dense and low-level. There are a few patterns
that are used throughout, though. One is the function-local static buffers,
e.g., the locales buffer and the facets buffer, in locale_body.cpp and
facet.cpp, respectively. They both start from a reasonable size and are grown
and shrunk according to the needs, but neither locales nor facets are ever
evicted from them. See:
locale_body:936 -- reduction of locale buffer
locale_body:1006 -- expansion of locale buffer
facet.cpp:397 -- reduction of facet buffer
facet.cpp:462 -- expansion of facet buffer
Facets buffer is guarded by a "static" guard in:
__rw_facet::_C_manage:366
The locales buffer is protected by a "static" guard in:
__rw_locale::_C_manage:880
[...] this is all investigative stuff for tomorrow. :-)
and I agree with Martin that breaking ABI in a minor release is really
not an option. I'm trying to find the best way of making these facets
thread-safe while inflicting the least horrible performance hit.
We are getting close to the point where we can summarize all these findings and
gauge an appropriate course of action.
I will run your tests tomorrow and let you know. :-)
That would be very helpful!
Liviu