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