[PATCH 6/8] msvcrt: Share __lc_time_data between threadlocinfo instances.
Chip Davis
cdavis at codeweavers.com
Fri Jan 31 04:08:14 CST 2020
My testing shows that unk[1] is some sort of refcount. I've updated a
few places with this knowledge.
Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
dlls/msvcr90/tests/msvcr90.c | 10 +++++-----
dlls/msvcrt/locale.c | 10 ++++++++--
dlls/msvcrt/msvcrt.h | 3 ++-
dlls/msvcrt/tests/time.c | 7 ++++---
4 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index 4e28cafea0d8..664ab49317a9 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -2072,7 +2072,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);
@@ -2147,7 +2147,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);
@@ -2230,7 +2230,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);
@@ -2312,7 +2312,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);
@@ -2391,7 +2391,7 @@ static void test__get_current_locale(void)
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 == 1, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
ok(l2->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l2->locinfo->lc_time_curr->unk);
- todo_wine ok(l2->locinfo->lc_time_curr->refcount == 3 || l2->locinfo->lc_time_curr->refcount == 2,
+ ok(l2->locinfo->lc_time_curr->refcount == 3 || l2->locinfo->lc_time_curr->refcount == 2,
"refcount = %d\n", l2->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index de77c83cbdea..5894990f55e4 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -131,7 +131,7 @@ MSVCRT___lc_time_data cloc_time_data =
#if _MSVCR_VER < 110
MAKELCID(LANG_ENGLISH, SORT_DEFAULT),
#endif
- {1, 0},
+ 1, 1,
{{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,
@@ -979,7 +979,8 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
MSVCRT_free(locinfo->ctype1);
}
- if(locinfo->lc_time_curr != &cloc_time_data)
+ if(!InterlockedDecrement(&locinfo->lc_time_curr->refcount)
+ && locinfo->lc_time_curr != &cloc_time_data)
MSVCRT_free(locinfo->lc_time_curr);
MSVCRT_free(locinfo);
@@ -1120,6 +1121,8 @@ static MSVCRT___lc_time_data* create_time_data(LCID lcid)
#else
cur->lcid = lcid;
#endif
+ cur->unk = 1;
+ cur->refcount = 1;
return cur;
}
@@ -1803,6 +1806,8 @@ 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;
+ 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)) {
@@ -1826,6 +1831,7 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
return NULL;
}
locinfo->lc_time_curr = &cloc_time_data;
+ InterlockedIncrement(&locinfo->lc_time_curr->refcount);
}
return locinfo;
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 244df7d23ccc..e5a22c68ee8b 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -146,7 +146,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 {
diff --git a/dlls/msvcrt/tests/time.c b/dlls/msvcrt/tests/time.c
index 45ed971ca89a..20212d19bfa5 100644
--- a/dlls/msvcrt/tests/time.c
+++ b/dlls/msvcrt/tests/time.c
@@ -47,7 +47,8 @@ typedef struct {
const char *date;
const char *time;
LCID lcid;
- int unk[2];
+ int unk;
+ int refcount;
} __lc_time_data;
static __time32_t (__cdecl *p_mkgmtime32)(struct tm*);
@@ -824,8 +825,8 @@ static void test_strftime(void)
return;
}
- /* TODO: find meaning of unk[0] */
- time_data.unk[0] = 1;
+ /* TODO: find meaning of unk */
+ time_data.unk = 1;
for (i=0; i<ARRAY_SIZE(tests_td); i++)
{
time_data.short_date = tests_td[i].short_date;
--
2.24.0
More information about the wine-devel
mailing list