Chip Davis : msvcrt: Share locale names between threadlocinfo instances.

Alexandre Julliard julliard at winehq.org
Wed Nov 18 15:48:01 CST 2020


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

Author: Chip Davis <cdavis at codeweavers.com>
Date:   Wed Nov 18 17:25:50 2020 +0100

msvcrt: Share locale names between threadlocinfo instances.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/locale.c | 57 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 43 insertions(+), 14 deletions(-)

diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index a305f88e808..b6c36ac4cf1 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -380,6 +380,24 @@ LCID MSVCRT_locale_to_LCID(const char *locale, unsigned short *codepage, BOOL *s
     return lcid;
 }
 
+static void copy_threadlocinfo_category(MSVCRT_pthreadlocinfo locinfo,
+        const MSVCRT_threadlocinfo *old_locinfo, int category)
+{
+    locinfo->lc_handle[category] = old_locinfo->lc_handle[category];
+    locinfo->lc_id[category] = old_locinfo->lc_id[category];
+    if(!locinfo->lc_category[category].locale) {
+        locinfo->lc_category[category].locale = old_locinfo->lc_category[category].locale;
+        locinfo->lc_category[category].refcount = old_locinfo->lc_category[category].refcount;
+        InterlockedIncrement(locinfo->lc_category[category].refcount);
+    }
+#if _MSVCR_VER >= 110
+    locinfo->lc_name[category] = old_locinfo->lc_name[category];
+    locinfo->lc_category[category].wrefcount = old_locinfo->lc_category[category].wrefcount;
+    if(locinfo->lc_category[category].wrefcount)
+        InterlockedIncrement(locinfo->lc_category[category].wrefcount);
+#endif
+}
+
 static BOOL init_category_name(const char *name, int len,
         MSVCRT_pthreadlocinfo locinfo, int category)
 {
@@ -934,12 +952,18 @@ 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);
-        MSVCRT_free(locinfo->lc_category[i].wrefcount);
+        if(!locinfo->lc_category[i].refcount
+                || !InterlockedDecrement(locinfo->lc_category[i].refcount)) {
+            MSVCRT_free(locinfo->lc_category[i].locale);
+            MSVCRT_free(locinfo->lc_category[i].refcount);
+        }
+        if(!locinfo->lc_category[i].wrefcount
+                || !InterlockedDecrement(locinfo->lc_category[i].wrefcount)) {
 #if _MSVCR_VER >= 110
-        MSVCRT_free(locinfo->lc_name[i]);
+            MSVCRT_free(locinfo->lc_name[i]);
 #endif
+            MSVCRT_free(locinfo->lc_category[i].wrefcount);
+        }
     }
 
     if(locinfo->lconv) {
@@ -1240,8 +1264,7 @@ 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);
     } 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)) {
@@ -1266,8 +1289,7 @@ 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);
     } else if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) {
         CPINFO cp_info;
         int j;
@@ -1354,8 +1376,7 @@ 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);
     } 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)) {
@@ -1632,8 +1653,7 @@ 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);
     } 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)) {
@@ -1748,8 +1768,7 @@ 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);
     } 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)) {
@@ -1883,6 +1902,8 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
         locinfo->lc_id[MSVCRT_LC_COLLATE] =
             newlocinfo->lc_id[MSVCRT_LC_COLLATE];
 
+        swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].wrefcount,
+                (void**)&newlocinfo->lc_category[MSVCRT_LC_COLLATE].wrefcount);
 #if _MSVCR_VER >= 110
         swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_COLLATE],
                 (void**)&newlocinfo->lc_name[MSVCRT_LC_COLLATE]);
@@ -1913,6 +1934,8 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
         swap_pointers((void**)&locinfo->pclmap, (void**)&newlocinfo->pclmap);
         swap_pointers((void**)&locinfo->pcumap, (void**)&newlocinfo->pcumap);
 
+        swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_CTYPE].wrefcount,
+                (void**)&newlocinfo->lc_category[MSVCRT_LC_CTYPE].wrefcount);
 #if _MSVCR_VER >= 110
         swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_CTYPE],
                 (void**)&newlocinfo->lc_name[MSVCRT_LC_CTYPE]);
@@ -1971,6 +1994,8 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
         locinfo->lconv->p_sign_posn = newlocinfo->lconv->p_sign_posn;
         locinfo->lconv->n_sign_posn = newlocinfo->lconv->n_sign_posn;
 
+        swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].wrefcount,
+                (void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].wrefcount);
 #if _MSVCR_VER >= 110
         swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_MONETARY],
                 (void**)&newlocinfo->lc_name[MSVCRT_LC_MONETARY]);
@@ -2004,6 +2029,8 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
                 (void**)&newlocinfo->lconv->_W_thousands_sep);
 #endif
 
+        swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].wrefcount,
+                (void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].wrefcount);
 #if _MSVCR_VER >= 110
         swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC],
                 (void**)&newlocinfo->lc_name[MSVCRT_LC_NUMERIC]);
@@ -2025,6 +2052,8 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
         swap_pointers((void**)&locinfo->lc_time_curr,
                 (void**)&newlocinfo->lc_time_curr);
 
+        swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_TIME].wrefcount,
+                (void**)&newlocinfo->lc_category[MSVCRT_LC_TIME].wrefcount);
 #if _MSVCR_VER >= 110
         swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_TIME],
                 (void**)&newlocinfo->lc_name[MSVCRT_LC_TIME]);




More information about the wine-cvs mailing list