[PATCH v2 2/8] msvcrt: Share locale names between threadlocinfo instances.
Chip Davis
cdavis at codeweavers.com
Fri Jan 31 16:29:57 CST 2020
Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
v2: Don't share VC11 locale names.
---
dlls/msvcr90/tests/msvcr90.c | 64 ++++++++++-------------------
dlls/msvcrt/locale.c | 79 ++++++++++++++++++++++++++++--------
2 files changed, 83 insertions(+), 60 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index f8e68ed2f630..b030c113853f 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -2024,15 +2024,11 @@ static void test__get_current_locale(void)
"same locale name pointers for LC_COLLATE\n");
ok(l->locinfo->lc_category[LC_COLLATE].refcount != l2->locinfo->lc_category[LC_COLLATE].refcount,
"same refcount pointers for LC_COLLATE\n");
- ok(l->locinfo->lc_category[LC_COLLATE].refcount, "null refcount pointer for LC_COLLATE\n");
- if(l->locinfo->lc_category[LC_COLLATE].refcount)
- ok(*l->locinfo->lc_category[LC_COLLATE].refcount == 1, "refcount = %d\n",
- *l->locinfo->lc_category[LC_COLLATE].refcount);
- ok(l2->locinfo->lc_category[LC_COLLATE].refcount, "null refcount pointer for LC_COLLATE\n");
- if(l2->locinfo->lc_category[LC_COLLATE].refcount)
- ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n",
- *l2->locinfo->lc_category[LC_COLLATE].refcount);
}
+ ok(*l->locinfo->lc_category[LC_COLLATE].refcount == 1, "refcount = %d\n",
+ *l->locinfo->lc_category[LC_COLLATE].refcount);
+ todo_wine ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n",
+ *l2->locinfo->lc_category[LC_COLLATE].refcount);
for(i = LC_CTYPE; i <= LC_MAX; i++) {
ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale,
"different locale name pointers for category %d\n", i);
@@ -2095,15 +2091,11 @@ static void test__get_current_locale(void)
"same locale name pointers for category %d\n", i);
ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount,
"same refcount pointers for category %d\n", i);
- ok(l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l->locinfo->lc_category[i].refcount)
- ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
- *l->locinfo->lc_category[i].refcount, i);
- ok(l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l2->locinfo->lc_category[i].refcount)
- ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
- *l2->locinfo->lc_category[i].refcount, i);
}
+ ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
+ *l->locinfo->lc_category[i].refcount, i);
+ todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
+ *l2->locinfo->lc_category[i].refcount, i);
}
for(i = LC_MONETARY; i <= LC_MAX; i++) {
ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale,
@@ -2174,15 +2166,11 @@ static void test__get_current_locale(void)
"same locale name pointers for category %d\n", i);
ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount,
"same refcount pointers for category %d\n", i);
- ok(l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l->locinfo->lc_category[i].refcount)
- ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
- *l->locinfo->lc_category[i].refcount, i);
- ok(l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l2->locinfo->lc_category[i].refcount)
- ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
- *l2->locinfo->lc_category[i].refcount, i);
}
+ ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
+ *l->locinfo->lc_category[i].refcount, i);
+ todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
+ *l2->locinfo->lc_category[i].refcount, i);
}
for(i = LC_NUMERIC; i <= LC_MAX; i++) {
ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale,
@@ -2261,15 +2249,11 @@ static void test__get_current_locale(void)
"same locale name pointers for category %d\n", i);
ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount,
"same refcount pointers for category %d\n", i);
- ok(l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l->locinfo->lc_category[i].refcount)
- ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
- *l->locinfo->lc_category[i].refcount, i);
- ok(l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l2->locinfo->lc_category[i].refcount)
- ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
- *l2->locinfo->lc_category[i].refcount, i);
}
+ ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
+ *l->locinfo->lc_category[i].refcount, i);
+ todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
+ *l2->locinfo->lc_category[i].refcount, i);
}
ok(l->locinfo->lc_category[LC_TIME].locale == l2->locinfo->lc_category[LC_TIME].locale,
"different locale name pointers for LC_TIME\n");
@@ -2341,21 +2325,17 @@ static void test__get_current_locale(void)
ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount);
}
- todo_wine {
- for(i = LC_MIN+1; i <= LC_MAX; i++) {
+ for(i = LC_MIN+1; i <= LC_MAX; i++) {
+ todo_wine {
ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale,
"same locale name pointers for category %d\n", i);
ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount,
"same refcount pointers for category %d\n", i);
- ok(l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l->locinfo->lc_category[i].refcount)
- ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
- *l->locinfo->lc_category[i].refcount, i);
- ok(l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i);
- if(l2->locinfo->lc_category[i].refcount)
- ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
- *l2->locinfo->lc_category[i].refcount, i);
}
+ ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n",
+ *l->locinfo->lc_category[i].refcount, i);
+ todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
+ *l2->locinfo->lc_category[i].refcount, i);
}
todo_wine {
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index f6e7631b4f50..df19326586bf 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -418,6 +418,15 @@ static BOOL init_category_name(const char *name, int len,
return TRUE;
}
+/* INTERNAL: Copy lc_handle, lc_id, and lc_category from one threadlocinfo to another */
+static void copy_threadlocinfo_category(MSVCRT_pthreadlocinfo locinfo, MSVCRT_pthreadlocinfo old_locinfo, int category)
+{
+ locinfo->lc_handle[category] = old_locinfo->lc_handle[category];
+ locinfo->lc_id[category] = old_locinfo->lc_id[category];
+ locinfo->lc_category[category] = old_locinfo->lc_category[category];
+ InterlockedIncrement(locinfo->lc_category[category].refcount);
+}
+
/* INTERNAL: Set lc_handle, lc_id and lc_category in threadlocinfo struct */
static BOOL update_threadlocinfo_category(LCID lcid, unsigned short cp,
MSVCRT_pthreadlocinfo locinfo, int category)
@@ -878,11 +887,14 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
return;
for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) {
- MSVCRT_free(locinfo->lc_category[i].locale);
- MSVCRT_free(locinfo->lc_category[i].refcount);
#if _MSVCR_VER >= 110
MSVCRT_free(locinfo->lc_name[i]);
#endif
+ if(!locinfo->lc_category[i].refcount
+ || InterlockedDecrement(locinfo->lc_category[i].refcount))
+ continue;
+ MSVCRT_free(locinfo->lc_category[i].locale);
+ MSVCRT_free(locinfo->lc_category[i].refcount);
}
if(locinfo->lconv) {
@@ -1200,8 +1212,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_COLLATE, category, old_locinfo,
lcid[MSVCRT_LC_COLLATE], cp[MSVCRT_LC_COLLATE])) {
- locinfo->lc_handle[MSVCRT_LC_COLLATE] = old_locinfo->lc_handle[MSVCRT_LC_COLLATE];
- locinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage = old_locinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage;
+ copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_COLLATE);
+ if(!set_lc_locale_name(locinfo, MSVCRT_LC_COLLATE)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
} else if(lcid[MSVCRT_LC_COLLATE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_COLLATE)) {
if(!update_threadlocinfo_category(lcid[MSVCRT_LC_COLLATE],
cp[MSVCRT_LC_COLLATE], locinfo, MSVCRT_LC_COLLATE)) {
@@ -1215,8 +1230,12 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
free_locinfo(locinfo);
return NULL;
}
- } else
- locinfo->lc_category[MSVCRT_LC_COLLATE].locale = MSVCRT__strdup("C");
+ } else {
+ if(!init_category_name("C", 1, locinfo, MSVCRT_LC_COLLATE)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
+ }
if(locale_name[MSVCRT_LC_CTYPE] &&
!init_category_name(locale_name[MSVCRT_LC_CTYPE],
@@ -1227,8 +1246,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_CTYPE, category, old_locinfo,
lcid[MSVCRT_LC_CTYPE], cp[MSVCRT_LC_CTYPE])) {
- locinfo->lc_handle[MSVCRT_LC_CTYPE] = old_locinfo->lc_handle[MSVCRT_LC_CTYPE];
- locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage = old_locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage;
+ copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_CTYPE);
+ if(!set_lc_locale_name(locinfo, MSVCRT_LC_CTYPE)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
} else if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) {
CPINFO cp_info;
int j;
@@ -1293,7 +1315,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
locinfo->lc_clike = 1;
locinfo->mb_cur_max = 1;
locinfo->pctype = MSVCRT__ctype+1;
- locinfo->lc_category[MSVCRT_LC_CTYPE].locale = MSVCRT__strdup("C");
+ if(!init_category_name("C", 1, locinfo, MSVCRT_LC_CTYPE)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
for(i=0; i<256; i++) {
if(locinfo->pctype[i] & MSVCRT__LEADBYTE)
@@ -1317,8 +1342,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_MONETARY, category, old_locinfo,
lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY])) {
- locinfo->lc_handle[MSVCRT_LC_MONETARY] = old_locinfo->lc_handle[MSVCRT_LC_MONETARY];
- locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage = old_locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage;
+ copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_MONETARY);
+ if(!set_lc_locale_name(locinfo, MSVCRT_LC_MONETARY)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
} else if(lcid[MSVCRT_LC_MONETARY] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_MONETARY)) {
if(!update_threadlocinfo_category(lcid[MSVCRT_LC_MONETARY],
cp[MSVCRT_LC_MONETARY], locinfo, MSVCRT_LC_MONETARY)) {
@@ -1585,7 +1613,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
locinfo->lconv->_W_negative_sign[0] = '\0';
#endif
- locinfo->lc_category[MSVCRT_LC_MONETARY].locale = MSVCRT__strdup("C");
+ if(!init_category_name("C", 1, locinfo, MSVCRT_LC_MONETARY)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
}
if(locale_name[MSVCRT_LC_NUMERIC] &&
@@ -1597,8 +1628,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_NUMERIC, category, old_locinfo,
lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC])) {
- locinfo->lc_handle[MSVCRT_LC_NUMERIC] = old_locinfo->lc_handle[MSVCRT_LC_NUMERIC];
- locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage = old_locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage;
+ copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_NUMERIC);
+ if(!set_lc_locale_name(locinfo, MSVCRT_LC_NUMERIC)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
} else if(lcid[MSVCRT_LC_NUMERIC] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_NUMERIC)) {
if(!update_threadlocinfo_category(lcid[MSVCRT_LC_NUMERIC],
cp[MSVCRT_LC_NUMERIC], locinfo, MSVCRT_LC_NUMERIC)) {
@@ -1703,7 +1737,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
locinfo->lconv->_W_thousands_sep[0] = '\0';
#endif
- locinfo->lc_category[MSVCRT_LC_NUMERIC].locale = MSVCRT__strdup("C");
+ if (!init_category_name("C", 1, locinfo, MSVCRT_LC_NUMERIC)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
}
if(locale_name[MSVCRT_LC_TIME] &&
@@ -1715,8 +1752,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_TIME, category, old_locinfo,
lcid[MSVCRT_LC_TIME], cp[MSVCRT_LC_TIME])) {
- locinfo->lc_handle[MSVCRT_LC_TIME] = old_locinfo->lc_handle[MSVCRT_LC_TIME];
- locinfo->lc_id[MSVCRT_LC_TIME].wCodePage = old_locinfo->lc_id[MSVCRT_LC_TIME].wCodePage;
+ copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_TIME);
+ if(!set_lc_locale_name(locinfo, MSVCRT_LC_TIME)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
} else if(lcid[MSVCRT_LC_TIME] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_TIME)) {
if(!update_threadlocinfo_category(lcid[MSVCRT_LC_TIME],
cp[MSVCRT_LC_TIME], locinfo, MSVCRT_LC_TIME)) {
@@ -1735,7 +1775,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
return NULL;
}
} else {
- locinfo->lc_category[MSVCRT_LC_TIME].locale = MSVCRT__strdup("C");
+ if(!init_category_name("C", 1, locinfo, MSVCRT_LC_TIME)) {
+ free_locinfo(locinfo);
+ return NULL;
+ }
locinfo->lc_time_curr = &cloc_time_data;
}
--
2.24.0
More information about the wine-devel
mailing list