On 09/05/12 14:09, Stefan Teleman wrote:
On Wed, Sep 5, 2012 at 10:52 AM, Martin Sebor <mse...@gmail.com> wrote:
[...]
OK so I did a little bit of testing, after looking at the *right*
__rw_guard class. :-)

I changed the std::numpunct class thusly:
[...]
And then:

template <class _CharT>
inline string numpunct<_CharT>::grouping () const
{
     if (!(_C_flags & _RW::__rw_gr)) {

         _RWSTD_MT_GUARD (_C_object_mutex);

         // double-test here to avoid re-writing an already written string
         if (!(_C_flags & _RW::__rw_gr)) {

             numpunct* const __self = _RWSTD_CONST_CAST (numpunct*, this);

             // [try to] get the grouping first (may throw)
             // then set a flag to avoid future initializations
             __self->_C_grouping  = do_grouping ();
             __self->_C_flags    |= _RW::__rw_gr;

         }
     }

     return _C_grouping;
}

I am afraid this would be unsafe, too (if I said otherwise earlier I was 
wrong). The compiler might re-arrange the protected assignments, such that 
another thread sees a partially updated object, where the flags are updated and 
the string not. I don't think we're going to get away with this here without 
either a simpler and more inefficient top-level locking, or doing away 
completely with the lazy initialization. Thoughts?

Liviu

Reply via email to