Module: wine Branch: master Commit: 4fc2b7293378be93275e316c3940e7d21b5bda09 URL: https://source.winehq.org/git/wine.git/?a=commit;h=4fc2b7293378be93275e316c3...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Nov 25 20:24:26 2020 +0100
msvcrt: Introduce flags field to describe locale stored in thread data.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcr90/tests/msvcr90.c | 4 ++-- dlls/msvcrt/locale.c | 44 ++++++++++++++++++++------------------------ dlls/msvcrt/main.c | 2 +- dlls/msvcrt/msvcrt.h | 5 ++++- 4 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index 08eb4a7ac64..deca9be47fe 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -1213,8 +1213,8 @@ static void test_getptd(void) todo_wine ok(ptd->have_locale == 1, "ptd->have_locale = %x\n", ptd->have_locale); p_configthreadlocale(1); todo_wine ok(mbcinfo == ptd->mbcinfo, "ptd->mbcinfo != mbcinfo\n"); - todo_wine ok(locinfo == ptd->locinfo, "ptd->locinfo != locinfo\n"); - todo_wine ok(ptd->have_locale == 3, "ptd->have_locale = %x\n", ptd->have_locale); + ok(locinfo == ptd->locinfo, "ptd->locinfo != locinfo\n"); + ok(ptd->have_locale == 3, "ptd->have_locale = %x\n", ptd->have_locale); ok(p_get_terminate() == ptd->terminate_handler, "ptd->terminate_handler != _get_terminate()\n"); ok(p_get_unexpected() == ptd->unexpected_handler, "ptd->unexpected_handler != _get_unexpected()\n"); } diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 0c4211dc197..2a66867928c 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -588,7 +588,7 @@ static BOOL update_threadlocinfo_category(LCID lcid, unsigned short cp, static MSVCRT_pthreadlocinfo* CDECL get_locinfo_ptr(void) { thread_data_t *data = msvcrt_get_thread_data();
- if(!data || !data->have_locale) + if(!data || !(data->locale_flags & LOCALE_THREAD)) return &MSVCRT_locale->locinfo;
return &data->locinfo; @@ -602,7 +602,7 @@ MSVCRT_pthreadlocinfo CDECL get_locinfo(void) { MSVCRT_pthreadmbcinfo* CDECL get_mbcinfo_ptr(void) { thread_data_t *data = msvcrt_get_thread_data();
- if(!data || !data->have_locale) + if(!data || !(data->locale_flags & LOCALE_THREAD)) return &MSVCRT_locale->mbcinfo;
return &data->mbcinfo; @@ -1142,7 +1142,7 @@ MSVCRT__locale_t CDECL get_current_locale_noalloc(MSVCRT__locale_t locale) thread_data_t *data = msvcrt_get_thread_data(); int i;
- if(!data || !data->have_locale) + if(!data || !(data->locale_flags & LOCALE_THREAD)) { _lock_locales(); *locale = *MSVCRT_locale; @@ -2101,39 +2101,35 @@ MSVCRT_wchar_t* CDECL MSVCRT__wsetlocale(int category, const MSVCRT_wchar_t* wlo int CDECL _configthreadlocale(int type) { thread_data_t *data = msvcrt_get_thread_data(); - MSVCRT__locale_t locale; int ret;
if(!data) return -1;
- ret = (data->have_locale ? MSVCRT__ENABLE_PER_THREAD_LOCALE : MSVCRT__DISABLE_PER_THREAD_LOCALE); + ret = (data->locale_flags & LOCALE_THREAD ? MSVCRT__ENABLE_PER_THREAD_LOCALE : + MSVCRT__DISABLE_PER_THREAD_LOCALE); + if(ret == type) + return ret; + + if(data->locale_flags & LOCALE_FREE) + { + free_locinfo(data->locinfo); + free_mbcinfo(data->mbcinfo); + data->locale_flags &= ~LOCALE_FREE; + }
if(type == MSVCRT__ENABLE_PER_THREAD_LOCALE) { - if(!data->have_locale) { - /* Copy current global locale */ - locale = MSVCRT__create_locale(MSVCRT_LC_ALL, MSVCRT_setlocale(MSVCRT_LC_ALL, NULL)); - if(!locale) - return -1; - - data->locinfo = locale->locinfo; - data->mbcinfo = locale->mbcinfo; - data->have_locale = TRUE; - MSVCRT_free(locale); - } + MSVCRT__locale_tstruct locale;
+ get_current_locale_noalloc(&locale); + data->locinfo = locale.locinfo; + data->mbcinfo = locale.mbcinfo; + data->locale_flags = LOCALE_FREE | LOCALE_THREAD; return ret; }
if(type == MSVCRT__DISABLE_PER_THREAD_LOCALE) { - if(data->have_locale) { - free_locinfo(data->locinfo); - free_mbcinfo(data->mbcinfo); - data->locinfo = MSVCRT_locale->locinfo; - data->mbcinfo = MSVCRT_locale->mbcinfo; - data->have_locale = FALSE; - } - + data->locale_flags = 0; return ret; }
diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c index 0c19f01b440..c47c454b367 100644 --- a/dlls/msvcrt/main.c +++ b/dlls/msvcrt/main.c @@ -75,7 +75,7 @@ static inline void msvcrt_free_tls_mem(void) MSVCRT_free(tls->time_buffer); MSVCRT_free(tls->tmpnam_buffer); MSVCRT_free(tls->wtmpnam_buffer); - if(tls->have_locale) { + if(tls->locale_flags & LOCALE_FREE) { free_locinfo(tls->locinfo); free_mbcinfo(tls->mbcinfo); } diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index a815285409e..5881ecc5d04 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -209,6 +209,9 @@ void CDECL __DestructExceptionObject(EXCEPTION_RECORD*); /* TLS data */ extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN;
+#define LOCALE_FREE 0x1 +#define LOCALE_THREAD 0x2 + /* Keep in sync with msvcr90/tests/msvcr90.c */ struct __thread_data { DWORD tid; @@ -235,7 +238,7 @@ struct __thread_data { int fpecode; MSVCRT_pthreadmbcinfo mbcinfo; MSVCRT_pthreadlocinfo locinfo; - BOOL have_locale; + int locale_flags; int unk5[1]; MSVCRT_terminate_function terminate_handler; MSVCRT_unexpected_function unexpected_handler;