Module: wine Branch: master Commit: a7f124eb5e57d8be36daa3e87edb66a9b6843e9c URL: https://source.winehq.org/git/wine.git/?a=commit;h=a7f124eb5e57d8be36daa3e87...
Author: Piotr Caban piotr@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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; }
/*********************************************************************