Piotr Caban : msvcrt: Introduce flags field to describe locale stored in thread data.

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


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

Author: Piotr Caban <piotr at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;




More information about the wine-cvs mailing list