Martin Sebor wrote: >Travis Vitek wrote: >> Martin Sebor wrote: >> >>> AFAIK, catopen() and catgets() are not required to be thread >>> safe so we need to guard calls to them across all instances of >>> the facet. >>> >> >> Yes, but the affected functions are doing more than just calling >> catgets() and catopen(). Since they are using shared data, they >> need to lock that shared data with a shared mutex. > >And unless I'm missing something, they are. > > _RWSTD_MT_STATIC_GUARD (__rw_open_cat_data); > >This provides mutual exclusion across all othe such guards >(i.e, those with the same type as an argument). >
Nope. See _defs.h... // synchronizes access by all objects holding the same mutex # define _RWSTD_MT_GUARD(mutex) \ _RW::__rw_guard _RWSTD_PASTE (__guard, __LINE__) (mutex) // synchronizes access by all threads holding the same mutex # define _RWSTD_MT_STATIC_GUARD(type) \ typedef _RW::__rw_type<type,__LINE__> _UniqueType; \ _RWSTD_MT_CLASS_GUARD(_UniqueType) // synchronizes access by all objects of the same type # define _RWSTD_MT_CLASS_GUARD(type) \ _RWSTD_MT_GUARD (_RW::__rw_get_static_mutex ((type*)0)) _RWSTD_MT_CLASS_GUARD locks a static mutex that unique for the type provided. This provides the behavior that you are describing above. _RWSTD_MT_STATIC_GUARD creates a unique type given a type and a line number. That new type is then used to get a handle to a static mutex. The only time two _RWSTD_MT_STATIC_GUARD lines are guarding the same mutex is if they happen to be on the same line number and have the same type argument. Travis