Travis Vitek wrote:
Martin Sebor wrote:
Farid Zaripov wrote:
The 22.locale.messages.cpp test fails due to using incorrect
guard type in functions from messages.cpp file. There used
_RWSTD_MT_STATIC_GUARD(), so that the functions are protected
from working simultaneously with itself only. But from every that
functions invoked __rw_manage_cat_data() which working with
shared global repository of open catalogs.
_RWSTD_MT_STATIC_GUARD() lock a static local mutex, which guards
the rest of the block from being entered by more than 1 thread
across the whole process.
Yes, that is the problem. The current static guard prevents multiple
threads from entering the same function simultaneously [i.e. two threads
cannot call __rw_cat_open simultaneously], but it does nothing to
prevent one thread from calling __rw_cat_open() and another thread from
calling __rw_cat_close() at the same time.
How come? Aren't all the calls guarded using the same mutex?
_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).
Since __rw_manage_cat_data
has shared data, access to it must be synchronized using one common
lock.
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.
Martin
* messages.cpp (__rw_cat_open): Use _RWSTD_MT_CLASS_GUARD instead of
_RWSTD_MT_STATIC_GUARD to synchronize acces to global repository of
open
catalogs.
(__rw_get_message): Ditto.
(__rw_get_locale): Ditto.
(__rw_cat_close): Ditto.
Martin