>Eric Lemings wrote:
>
>Please peer review the following patch at your earliest convenience.
>

Brad,

I don't think that this patch is going to work. The unnecessary changes
to the __rw_setlocale ctor and dtor will cause new failures.

The __rw_setlocale type is supposed to hold the lock for its lifetime to
prevent other __rw_setlocale instances from being created and changing
the locale. Your change prevents concurrent calls to setlocale() through
__rw_setlocale() instances, but it doesn't prevent multiple
__rw_setlocale instances from existing simultaneously.

Travis


>-----
>$ svn diff
>Index: src/setlocale.h
>===================================================================
>--- src/setlocale.h     (revision 644426)
>+++ src/setlocale.h     (working copy)
>@@ -58,6 +58,9 @@
>         return _C_name;
>     }
>
>+    static const char* __rw_curlocale (int);
>+    static bool __rw_newlocale (const char*, int);
>+
> private:
>
>     __rw_setlocale (const __rw_setlocale&);   // not defined
>Index: src/setlocale.cpp
>===================================================================
>--- src/setlocale.cpp   (revision 644426)
>+++ src/setlocale.cpp   (working copy)
>@@ -80,11 +80,8 @@
> __rw_setlocale::__rw_setlocale (const char *locname, int cat, int
>nothrow)
>     : _C_name (0), _C_guard (1), _C_cat (cat)
> {
>-    // acquire global per-process lock
>-    __rw_setlocale_mutex._C_acquire ();
>-
>     // retrieve previous locale name and check if it is already set
>-    const char* const curname = ::setlocale (cat, 0);
>+    const char* const curname = __rw_curlocale (cat);
>
>     if (curname) {
>
>@@ -101,14 +98,13 @@
>
>         ::memcpy (_C_name, curname, size);
>
>-        if (::setlocale (cat, locname)) {
>+        if (__rw_newlocale (locname, cat)) {
>
>             // a NULL name is only used when we want to use the object
>             // as a retriever for the name of the current locale;
>             // no need for a lock then
>             if (!locname) {
>                 _C_guard = 0;
>-                __rw_setlocale_mutex._C_release ();
>             }
>
>             return;
>@@ -122,7 +118,6 @@
>
>     // bad locales OR bad locale names OR bad locale categories
>     _C_guard = 0;
>-    __rw_setlocale_mutex._C_release ();
>
>     // failure in setting the locale
>     _RWSTD_REQUIRES (nothrow, (_RWSTD_ERROR_LOCALE_BAD_NAME,
>@@ -131,6 +126,25 @@
> }
>
>
>+/*static*/ const char*
>+__rw_setlocale::__rw_curlocale (int cat)
>+{
>+    __rw_setlocale_mutex._C_acquire ();
>+    const char* const curname = ::setlocale (cat, 0);
>+    __rw_setlocale_mutex._C_release ();
>+    return curname;
>+}
>+
>+/*static*/ bool
>+__rw_setlocale::__rw_newlocale (const char* locname, int cat)
>+{
>+    __rw_setlocale_mutex._C_acquire ();
>+    bool changed = (0 != ::setlocale (cat, locname));
>+    __rw_setlocale_mutex._C_release ();
>+    return changed;
>+}
>+
>+
> // dtor restores the C library locale that
> // was in effect when the object was constructed
> __rw_setlocale::~__rw_setlocale ()
>Index: src/locale_global.cpp
>===================================================================
>--- src/locale_global.cpp       (revision 644426)
>+++ src/locale_global.cpp       (working copy)
>@@ -54,8 +54,7 @@
>
>         // assumes all locale names (i.e., including those of combined
>         // locales) are in a format understandable by setlocale()
>-        const _RW::__rw_setlocale clocale (rhs.name().c_str(),
>_RWSTD_LC_ALL);
>-        _RWSTD_UNUSED(clocale);
>+        _RW::__rw_setlocale::__rw_newlocale (rhs.name().c_str(),
>_RWSTD_LC_ALL);
>
>         // FIXME:
>         // handle unnamed locales (i.e., locales containing
>non-standard
>-----
>
>Thanks,
>Brad.
>

Reply via email to