Chip Davis : msvcrt: Share __lc_time_data between threadlocinfo instances.

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


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

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

msvcrt: Share __lc_time_data between threadlocinfo instances.

My testing shows that unk[1] is some sort of refcount.

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

---

 dlls/msvcr90/tests/msvcr90.c |  8 ++++----
 dlls/msvcrt/locale.c         | 10 ++++++++--
 dlls/msvcrt/msvcrt.h         |  3 ++-
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index 694f01257c5..6168bcfb242 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -2084,7 +2084,7 @@ static void test__get_current_locale(void)
         todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
 
     ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n");
-    todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
+    ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
     todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
 
     p__free_locale(l2);
@@ -2159,7 +2159,7 @@ static void test__get_current_locale(void)
         todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
 
     ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n");
-    todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
+    ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
     todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
 
     p__free_locale(l2);
@@ -2240,7 +2240,7 @@ static void test__get_current_locale(void)
     ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n");
 
     ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n");
-    todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
+    ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
     todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
 
     p__free_locale(l2);
@@ -2322,7 +2322,7 @@ static void test__get_current_locale(void)
     ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n");
 
     ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n");
-    todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
+    ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk);
     todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
 
     p__free_locale(l2);
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index b2108182341..18a4f006b11 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -109,7 +109,7 @@ MSVCRT___lc_time_data cloc_time_data =
 #if _MSVCR_VER < 110
     MAKELCID(LANG_ENGLISH, SORT_DEFAULT),
 #endif
-    {1, 0},
+    1, 0,
     {{sun, mon, tue, wed, thu, fri, sat,
       sunday, monday, tuesday, wednesday, thursday, friday, saturday,
       jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec,
@@ -1103,7 +1103,8 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
         MSVCRT_free((void*)locinfo->pcumap);
     }
 
-    if(locinfo->lc_time_curr != &cloc_time_data)
+    if(locinfo->lc_time_curr && locinfo->lc_time_curr != &cloc_time_data
+            && !InterlockedDecrement(&locinfo->lc_time_curr->refcount))
         MSVCRT_free(locinfo->lc_time_curr);
 
     MSVCRT_free(locinfo);
@@ -1237,6 +1238,8 @@ static MSVCRT___lc_time_data* create_time_data(LCID lcid)
 #else
     cur->lcid = lcid;
 #endif
+    cur->unk = 1;
+    cur->refcount = 1;
 
     return cur;
 }
@@ -1889,6 +1892,9 @@ 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])) {
         copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_TIME);
+        locinfo->lc_time_curr = old_locinfo->lc_time_curr;
+        if(locinfo->lc_time_curr != &cloc_time_data)
+            InterlockedIncrement(&locinfo->lc_time_curr->refcount);
     } 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)) {
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index cf1caea6729..ec8fa268e48 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -149,7 +149,8 @@ typedef struct {
 #if _MSVCR_VER < 110
     LCID lcid;
 #endif
-    int  unk[2];
+    int unk;
+    int refcount;
     union {
         const MSVCRT_wchar_t *wstr[43];
         struct {




More information about the wine-cvs mailing list