From 898abfc18f409357939e66cd9a6767d4bc5b0672 Mon Sep 17 00:00:00 2001 From: Chip Davis Date: Wed, 18 Nov 2020 17:26:15 +0100 Subject: [PATCH] msvcrt: Share __lc_time_data between threadlocinfo instances. My testing shows that unk[1] is some sort of refcount. Signed-off-by: Chip Davis Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- 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 { -- 2.11.4.GIT