The method for initializing the facet id is not currently thread safe.
If a thread enters __rw_facet_id::_C_init() and is preempted after
checking _C_id, a second thread can do the same check, increment the
static counter, assign the facet id, and then return. The preempted
thread would increment the static counter again, assign a new value to
the facet id.
This could cause has_facet, use_facet, or locale constructor to fail
unexpectedly.
2007-09-28 Travis Vitek <[EMAIL PROTECTED]>
* facet.cpp (_C_init): initialize facet id in a threadsafe
manner.
Index: facet.cpp
===================================================================
--- facet.cpp (revision 578875)
+++ facet.cpp (working copy)
@@ -597,17 +597,15 @@
_RWSTD_SIZE_T __rw_facet_id::_C_init () const
{
+ _RWSTD_MT_STATIC_GUARD(_RW::__rw_facet_id);
+
// return immediately if already initialized
if (_C_id)
return _C_id;
- // atomically increment id generator
- // the above initialization is already guarded and the
initialization
- // of standard facets has a chance of completing at the step above
-
// generate a unique id
const _RWSTD_SIZE_T new_id =
- _RWSTD_ATOMIC_PREINCREMENT (__rw_id_gen, false);
+ ++__rw_id_gen;
#ifndef _RWSTD_NO_MUTABLE