Module: wine Branch: master Commit: d5b2c3f233d2a7263f3b79133ce6216fa991c1f2 URL: https://source.winehq.org/git/wine.git/?a=commit;h=d5b2c3f233d2a7263f3b79133...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Nov 25 20:24:30 2020 +0100
msvcrt: Lock _MB_CP_LOCK lock in setmbcp.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/locale.c | 12 ++++-------- dlls/msvcrt/mbcs.c | 28 ++++++++++++++++++---------- dlls/msvcrt/msvcrt.h | 1 - 3 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 2a66867928c..82a499c5637 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -599,18 +599,14 @@ MSVCRT_pthreadlocinfo CDECL get_locinfo(void) { return *get_locinfo_ptr(); }
-MSVCRT_pthreadmbcinfo* CDECL get_mbcinfo_ptr(void) { +/* INTERNAL: returns pthreadmbcinfo struct */ +MSVCRT_pthreadmbcinfo CDECL get_mbcinfo(void) { thread_data_t *data = msvcrt_get_thread_data();
if(!data || !(data->locale_flags & LOCALE_THREAD)) - return &MSVCRT_locale->mbcinfo; - - return &data->mbcinfo; -} + return MSVCRT_locale->mbcinfo;
-/* INTERNAL: returns pthreadmbcinfo struct */ -MSVCRT_pthreadmbcinfo CDECL get_mbcinfo(void) { - return *get_mbcinfo_ptr(); + return data->mbcinfo; }
/* INTERNAL: constructs string returned by setlocale */ diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index a920dcea5f1..d4434209a43 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -28,6 +28,7 @@ #include <mbctype.h>
#include "msvcrt.h" +#include "mtdll.h" #include "winnls.h" #include "wine/debug.h"
@@ -209,9 +210,6 @@ int CDECL ___mb_cur_max_l_func(MSVCRT__locale_t locale) } #endif
-/********************************************************************* - * INTERNAL: _setmbcp_l - */ MSVCRT_threadmbcinfo* create_mbcinfo(int cp, LCID lcid, MSVCRT_threadmbcinfo *old_mbcinfo) { MSVCRT_threadmbcinfo *mbcinfo; @@ -386,20 +384,30 @@ MSVCRT_threadmbcinfo* create_mbcinfo(int cp, LCID lcid, MSVCRT_threadmbcinfo *ol */ int CDECL _setmbcp(int cp) { - MSVCRT_threadmbcinfo **old_mbcinfo = get_mbcinfo_ptr(); + thread_data_t *data = msvcrt_get_thread_data(); MSVCRT_threadmbcinfo *mbcinfo;
- mbcinfo = create_mbcinfo(cp, -1, *old_mbcinfo); - if(!mbcinfo) { + mbcinfo = create_mbcinfo(cp, -1, get_mbcinfo()); + if(!mbcinfo) + { *MSVCRT__errno() = MSVCRT_EINVAL; return -1; }
- free_mbcinfo(*old_mbcinfo); - *old_mbcinfo = mbcinfo; - - if(mbcinfo == MSVCRT_locale->mbcinfo) + if(data->locale_flags & LOCALE_THREAD) + { + if(data->locale_flags & LOCALE_FREE) + free_mbcinfo(data->mbcinfo); + data->mbcinfo = mbcinfo; + } + else + { + _lock(_MB_CP_LOCK); + free_mbcinfo(MSVCRT_locale->mbcinfo); + MSVCRT_locale->mbcinfo = mbcinfo; memcpy(MSVCRT_mbctype, MSVCRT_locale->mbcinfo->mbctype, sizeof(MSVCRT_mbctype)); + _unlock(_MB_CP_LOCK); + } return 0; }
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 5881ecc5d04..52aafcff869 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -1008,7 +1008,6 @@ MSVCRT__locale_t CDECL get_current_locale_noalloc(MSVCRT__locale_t locale) DECLS void CDECL free_locale_noalloc(MSVCRT__locale_t locale) DECLSPEC_HIDDEN; MSVCRT_pthreadlocinfo CDECL get_locinfo(void) DECLSPEC_HIDDEN; MSVCRT_pthreadmbcinfo CDECL get_mbcinfo(void) DECLSPEC_HIDDEN; -MSVCRT_pthreadmbcinfo* CDECL get_mbcinfo_ptr(void) DECLSPEC_HIDDEN; void __cdecl MSVCRT__free_locale(MSVCRT__locale_t); MSVCRT_threadmbcinfo* create_mbcinfo(int, LCID, MSVCRT_threadmbcinfo*) DECLSPEC_HIDDEN; void free_locinfo(MSVCRT_pthreadlocinfo) DECLSPEC_HIDDEN;