Piotr Caban : msvcrt: Make old locale access thread-safe in setlocale.

Alexandre Julliard julliard at winehq.org
Wed Nov 25 15:58:55 CST 2020


Module: wine
Branch: master
Commit: a7f124eb5e57d8be36daa3e87edb66a9b6843e9c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a7f124eb5e57d8be36daa3e87edb66a9b6843e9c

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Nov 25 20:24:41 2020 +0100

msvcrt: Make old locale access thread-safe in setlocale.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/locale.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index 2502e556ee2..6d891c3a8e0 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -601,15 +601,6 @@ void CDECL _unlock_locales(void)
     _unlock(_SETLOCALE_LOCK);
 }
 
-static MSVCRT_pthreadlocinfo* CDECL get_locinfo_ptr(void) {
-    thread_data_t *data = msvcrt_get_thread_data();
-
-    if(!data || !(data->locale_flags & LOCALE_THREAD))
-        return &MSVCRT_locale->locinfo;
-
-    return &data->locinfo;
-}
-
 static void CDECL grab_locinfo(MSVCRT_pthreadlocinfo locinfo)
 {
     int i;
@@ -2041,8 +2032,8 @@ MSVCRT__locale_t CDECL MSVCRT__wcreate_locale(int category, const MSVCRT_wchar_t
  */
 char* CDECL MSVCRT_setlocale(int category, const char* locale)
 {
-    MSVCRT_pthreadlocinfo *plocinfo = get_locinfo_ptr();
-    MSVCRT_pthreadlocinfo locinfo = *plocinfo, newlocinfo;
+    thread_data_t *data = msvcrt_get_thread_data();
+    MSVCRT_pthreadlocinfo locinfo = get_locinfo(), newlocinfo;
 
     if(category<MSVCRT_LC_MIN || category>MSVCRT_LC_MAX)
         return NULL;
@@ -2063,26 +2054,34 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
     if(locale[0] != 'C' || locale[1] != '\0')
         initial_locale = FALSE;
 
-    _lock_locales();
-    free_locinfo(locinfo);
-    *plocinfo = newlocinfo;
-    _unlock_locales();
-
-    if(newlocinfo == MSVCRT_locale->locinfo) {
+    if(data->locale_flags & LOCALE_THREAD)
+    {
+        if(data->locale_flags & LOCALE_FREE)
+            free_locinfo(data->locinfo);
+        data->locinfo = newlocinfo;
+    }
+    else
+    {
         int i;
 
+        _lock_locales();
+        free_locinfo(MSVCRT_locale->locinfo);
+        MSVCRT_locale->locinfo = newlocinfo;
+
         MSVCRT___lc_codepage = newlocinfo->lc_codepage;
         MSVCRT___lc_collate_cp = newlocinfo->lc_collate_cp;
         MSVCRT___mb_cur_max = newlocinfo->mb_cur_max;
         MSVCRT__pctype = newlocinfo->pctype;
         for(i=MSVCRT_LC_MIN; i<=MSVCRT_LC_MAX; i++)
             MSVCRT___lc_handle[i] = MSVCRT_locale->locinfo->lc_handle[i];
+        _unlock_locales();
+        update_thread_locale(data);
     }
 
     if(category == MSVCRT_LC_ALL)
-        return construct_lc_all(newlocinfo);
+        return construct_lc_all(data->locinfo);
 
-    return newlocinfo->lc_category[category].locale;
+    return data->locinfo->lc_category[category].locale;
 }
 
 /*********************************************************************




More information about the wine-cvs mailing list