[PATCH v2 4/8] msvcrt: Share ctype tables between threadlocinfo instances.
Chip Davis
cdavis at codeweavers.com
Mon Feb 3 20:13:14 CST 2020
Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
v2: Fix type mismatch warnings. Fix a leak.
---
dlls/msvcr90/tests/msvcr90.c | 16 +++++-----
dlls/msvcrt/locale.c | 60 +++++++++++++++++++++---------------
2 files changed, 43 insertions(+), 33 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index 693b8a30c5c1..038e16a1d326 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -2120,10 +2120,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");
@@ -2195,10 +2195,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");
@@ -2276,10 +2276,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");
@@ -2352,10 +2352,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 3723c14d483b..6518306ff882 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 unsigned char cloc_clmap[256];
+static unsigned 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,16 @@ 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);
+ }
+ return TRUE;
+}
+
/* INTERNAL: Map a synonym to an ISO code */
static void remap_synonym(char *name)
{
@@ -926,11 +939,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);
+ MSVCRT_free(locinfo->pclmap);
+ MSVCRT_free(locinfo->pcumap);
+ }
if(locinfo->lc_time_curr != &cloc_time_data)
MSVCRT_free(locinfo->lc_time_curr);
@@ -1198,13 +1211,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)) {
@@ -1254,6 +1260,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;
@@ -1274,7 +1290,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;
}
@@ -1315,7 +1333,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)) {
@@ -1323,17 +1341,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