incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <mse...@gmail.com>
Subject Re: STDCXX-1056 [was: Re: STDCXX forks]
Date Thu, 06 Sep 2012 16:16:54 GMT
On 09/06/2012 09:58 AM, Stefan Teleman wrote:
> On Thu, Sep 6, 2012 at 9:16 AM, Liviu Nicoara<nikkoara@hates.ms>  wrote:
>
>> I think Stefan is referring to adding a mutex member variable to the facet
>> in question and breaking binary compatibility. If that is the case I have
>> confused things when I suggested exactly that, earlier. A cursory read
>> through the __rw_facet source shows that inherits from __rw_synchronized in
>> MT builds, therefore each facet carries its own mutex member.
>
>> On 09/05/12 23:51, Martin Sebor wrote:
>>> We don't need to add a new mutex -- we can use the __rw_facet
>>> member for the locking. Or did you mean something else?
>
> A possible implementation using the __rw_facet mutex could look like this:
>
> template<class _CharT>
> inline string numpunct<_CharT>::grouping () const
> {
>      if (!(_C_flags&  _RW::__rw_gr)) {
>
>          numpunct* const __self = _RWSTD_CONST_CAST (numpunct*, this);
>
>          _RWSTD_MT_GUARD (__self->_C_mutex);
>
>          if (!(_C_flags&  _RW::__rw_gr)) {
>
>              // [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;
> }
>
> Except that it will not work. Because the __rw_facet mutex member is
> being locked  in file ../src/facet.cpp in function
> __rw_facet::_C_manage at line 366:
>
> // acquire lock
> _RWSTD_MT_STATIC_GUARD (_RW::__rw_facet);

This locks a different mutex, one unrelated to __rw_facet::_C_mutex.

Look at the implementation of _RWSTD_MT_STATIC_GUARD() in rw/_defs.h:

   #  define _RWSTD_MT_STATIC_GUARD(type)                         \
             typedef _RW::__rw_type<type,__LINE__> _UniqueType;   \
             _RWSTD_MT_CLASS_GUARD (_UniqueType)

   #  define _RWSTD_MT_CLASS_GUARD(type)                           \
             _RWSTD_MT_GUARD (_RW::__rw_get_static_mutex ((type*)0))

and then at __rw_get_static_mutex in rw/_mutex.h. It gets a static
("global") mutex from a "mutex factory" via template instantiation:

   __rw_static_mutex<__rw_facet>::_C_mutex;

>
> This will deadlock because this is the mutex already locked by
> std::numpunct<T>::grouping().
>
> I've already tested this with 3 compilers, and, it does indeed deadlock.

Something else must be locking the mutex then. I quickly looked
at __rw_get_punct (and __rw_get_numpunct) in punct.cpp but I
couldn't find any signs of the mutex being locked there. The
only thing I see being locked there is the global C locale. If
it's not the callee it has to be the caller.

>
> So yes, I did indeed mean something different. I meant adding another
> mutex data member to the numpunct class.

We can't (and shouldn't need to) add one. We need to be able to
make do with the existing member. That's what it's there for.

Martin

>
> --Stefan
>


Mime
View raw message