[PATCH 3/8] msvcrt: Share ctype tables between threadlocinfo instances.

Chip Davis cdavis at codeweavers.com
Fri Jan 31 16:29:58 CST 2020


Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
 dlls/msvcr90/tests/msvcr90.c | 16 +++++-----
 dlls/msvcrt/locale.c         | 59 +++++++++++++++++++++---------------
 2 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index b030c113853f..4e28cafea0d8 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -2114,10 +2114,10 @@ static void test__get_current_locale(void)
                 l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
         ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n",
                 l->locinfo->lc_clike, l2->locinfo->lc_clike);
+        ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
     }
-    ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
+    ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
     todo_wine {
-        ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
         ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n");
         ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n");
         ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n");
@@ -2189,10 +2189,10 @@ static void test__get_current_locale(void)
                 l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
         ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n",
                 l->locinfo->lc_clike, l2->locinfo->lc_clike);
+        ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
     }
-    ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
+    ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
     todo_wine {
-        ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
         ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n");
         ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n");
         ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n");
@@ -2270,10 +2270,10 @@ static void test__get_current_locale(void)
                 l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
         ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n",
                 l->locinfo->lc_clike, l2->locinfo->lc_clike);
+        ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
     }
-    ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
+    ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
     todo_wine {
-        ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
         ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n");
         ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n");
         ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n");
@@ -2346,10 +2346,10 @@ static void test__get_current_locale(void)
                 l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
         ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n",
                 l->locinfo->lc_clike, l2->locinfo->lc_clike);
+        ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
     }
-    ok(l->locinfo->lc_clike, "non-C locale is C-like\n");
+    ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
     todo_wine {
-        ok(!l2->locinfo->lc_clike, "C locale is not C-like\n");
         ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n");
         ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n");
         ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n");
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index df19326586bf..e43673c1fa40 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -55,6 +55,9 @@ BOOL initial_locale = TRUE;
 #define MSVCRT_LEADBYTE  0x8000
 #define MSVCRT_C1_DEFINED 0x200
 
+static char cloc_clmap[256];
+static char cloc_cumap[256];
+
 static const MSVCRT_wchar_t sun[] = {'S','u','n',0};
 static const MSVCRT_wchar_t mon[] = {'M','o','n',0};
 static const MSVCRT_wchar_t tue[] = {'T','u','e',0};
@@ -163,6 +166,15 @@ static const char * const _country_synonyms[] =
     "spanish-modern", "esn"
 };
 
+static BOOL WINAPI init_cloc_casemap(PINIT_ONCE once, void *param, void **context)
+{
+    int i;
+    for(i=0; i<256; i++) {
+        cloc_clmap[i] = (i>='A' && i<='Z' ? i-'A'+'a' : i);
+        cloc_cumap[i] = (i>='a' && i<='z' ? i-'a'+'A' : i);
+    }
+}
+
 /* INTERNAL: Map a synonym to an ISO code */
 static void remap_synonym(char *name)
 {
@@ -924,11 +936,11 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
     MSVCRT_free(locinfo->lconv_mon_refcount);
     MSVCRT_free(locinfo->lconv);
 
-    MSVCRT_free(locinfo->ctype1_refcount);
-    MSVCRT_free(locinfo->ctype1);
-
-    MSVCRT_free(locinfo->pclmap);
-    MSVCRT_free(locinfo->pcumap);
+    if(locinfo->ctype1_refcount
+            && !InterlockedDecrement(locinfo->ctype1_refcount)) {
+        MSVCRT_free(locinfo->ctype1_refcount);
+        MSVCRT_free(locinfo->ctype1);
+    }
 
     if(locinfo->lc_time_curr != &cloc_time_data)
         MSVCRT_free(locinfo->lc_time_curr);
@@ -1196,13 +1208,6 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
     }
     memset(locinfo->lconv, 0, sizeof(struct MSVCRT_lconv));
 
-    locinfo->pclmap = MSVCRT_malloc(sizeof(char[256]));
-    locinfo->pcumap = MSVCRT_malloc(sizeof(char[256]));
-    if(!locinfo->pclmap || !locinfo->pcumap) {
-        free_locinfo(locinfo);
-        return NULL;
-    }
-
     if(locale_name[MSVCRT_LC_COLLATE] &&
             !init_category_name(locale_name[MSVCRT_LC_COLLATE],
                 locale_len[MSVCRT_LC_COLLATE], locinfo, MSVCRT_LC_COLLATE)) {
@@ -1251,6 +1256,16 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
             free_locinfo(locinfo);
             return NULL;
         }
+        locinfo->lc_codepage = old_locinfo->lc_codepage;
+        locinfo->lc_clike = old_locinfo->lc_clike;
+        locinfo->mb_cur_max = old_locinfo->mb_cur_max;
+        locinfo->ctype1 = old_locinfo->ctype1;
+        locinfo->ctype1_refcount = old_locinfo->ctype1_refcount;
+        locinfo->pctype = old_locinfo->pctype;
+        locinfo->pclmap = old_locinfo->pclmap;
+        locinfo->pcumap = old_locinfo->pcumap;
+        if(locinfo->ctype1_refcount)
+            InterlockedIncrement(locinfo->ctype1_refcount);
     } else if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) {
         CPINFO cp_info;
         int j;
@@ -1271,7 +1286,9 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
 
         locinfo->ctype1_refcount = MSVCRT_malloc(sizeof(int));
         locinfo->ctype1 = MSVCRT_malloc(sizeof(short[257]));
-        if(!locinfo->ctype1_refcount || !locinfo->ctype1) {
+        locinfo->pclmap = MSVCRT_malloc(sizeof(char[256]));
+        locinfo->pcumap = MSVCRT_malloc(sizeof(char[256]));
+        if(!locinfo->ctype1_refcount || !locinfo->ctype1 || !locinfo->pclmap || !locinfo->pcumap) {
             free_locinfo(locinfo);
             return NULL;
         }
@@ -1312,7 +1329,7 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
         LCMapStringA(lcid[MSVCRT_LC_CTYPE], LCMAP_UPPERCASE, buf, 256,
                 (char*)locinfo->pcumap, 256);
     } else {
-        locinfo->lc_clike = 1;
+        static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
         locinfo->mb_cur_max = 1;
         locinfo->pctype = MSVCRT__ctype+1;
         if(!init_category_name("C", 1, locinfo, MSVCRT_LC_CTYPE)) {
@@ -1320,17 +1337,9 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
             return NULL;
         }
 
-        for(i=0; i<256; i++) {
-            if(locinfo->pctype[i] & MSVCRT__LEADBYTE)
-                buf[i] = ' ';
-            else
-                buf[i] = i;
-        }
-
-        for(i=0; i<256; i++) {
-            locinfo->pclmap[i] = (i>='A' && i<='Z' ? i-'A'+'a' : i);
-            locinfo->pcumap[i] = (i>='a' && i<='z' ? i-'a'+'A' : i);
-        }
+        InitOnceExecuteOnce(&once, init_cloc_casemap, NULL, NULL);
+        locinfo->pclmap = cloc_clmap;
+        locinfo->pcumap = cloc_cumap;
     }
 
     if(locale_name[MSVCRT_LC_MONETARY] &&
-- 
2.24.0




More information about the wine-devel mailing list