[PATCH v3 resend 8/8] msvcrt: Increment refcounts for all locale data in _get_current_locale().
Chip Davis
cdavis at codeweavers.com
Mon Feb 3 20:13:18 CST 2020
Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
v3: Make sure we decrement refcounts, too.
---
dlls/msvcr90/tests/msvcr90.c | 46 ++++++++++++++++++------------------
dlls/msvcrt/locale.c | 30 +++++++++++++++++++----
2 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index eda774210c7b..c2cf14f37e4c 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -2027,14 +2027,14 @@ static void test__get_current_locale(void)
"same refcount pointers for LC_COLLATE\n");
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",
+ 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);
ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount,
"different refcount pointers for category %d\n", i);
- todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n",
+ ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n",
*l->locinfo->lc_category[i].refcount, i);
}
@@ -2051,23 +2051,23 @@ static void test__get_current_locale(void)
ok(l->locinfo->pclmap == l2->locinfo->pclmap, "different clmap pointers\n");
ok(l->locinfo->pcumap == l2->locinfo->pcumap, "different cumap pointers\n");
ok(l->locinfo->ctype1_refcount == l2->locinfo->ctype1_refcount, "different ctype1_refcount pointers\n");
- todo_wine ok(*l->locinfo->ctype1_refcount == 3, "refcount = %d\n", *l->locinfo->ctype1_refcount);
+ ok(*l->locinfo->ctype1_refcount == 3, "refcount = %d\n", *l->locinfo->ctype1_refcount);
ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n");
ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n");
- todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
+ ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n");
ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n");
- todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
+ ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n");
ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n");
- todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
+ 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");
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);
+ ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2084,7 +2084,7 @@ static void test__get_current_locale(void)
"same refcount pointers for category %d\n", 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",
+ 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++) {
@@ -2092,7 +2092,7 @@ static void test__get_current_locale(void)
"different locale name pointers for category %d\n", i);
ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount,
"different refcount pointers for category %d\n", i);
- todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n",
+ ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n",
*l->locinfo->lc_category[i].refcount, i);
}
@@ -2114,19 +2114,19 @@ static void test__get_current_locale(void)
ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n");
ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n");
- todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
+ ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n");
ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n");
- todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
+ ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n");
ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n");
- todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
+ 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");
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);
+ ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2143,7 +2143,7 @@ static void test__get_current_locale(void)
"same refcount pointers for category %d\n", 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",
+ 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++) {
@@ -2151,7 +2151,7 @@ static void test__get_current_locale(void)
"different locale name pointers for category %d\n", i);
ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount,
"different refcount pointers for category %d\n", i);
- todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n",
+ ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n",
*l->locinfo->lc_category[i].refcount, i);
}
@@ -2174,11 +2174,11 @@ static void test__get_current_locale(void)
ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n");
ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n");
ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
- todo_wine ok(*l2->locinfo->lconv_intl_refcount == 2, "refcount = %d\n", *l2->locinfo->lconv_intl_refcount);
+ ok(*l2->locinfo->lconv_intl_refcount == 2, "refcount = %d\n", *l2->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n");
ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n");
- todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
+ ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n");
ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n");
@@ -2187,7 +2187,7 @@ static void test__get_current_locale(void)
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n");
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);
+ ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2204,14 +2204,14 @@ static void test__get_current_locale(void)
"same refcount pointers for category %d\n", 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",
+ 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");
ok(l->locinfo->lc_category[LC_TIME].refcount == l2->locinfo->lc_category[LC_TIME].refcount,
"different refcount pointers for LC_TIME\n");
- todo_wine ok(*l->locinfo->lc_category[LC_TIME].refcount == 3, "refcount = %d\n",
+ ok(*l->locinfo->lc_category[LC_TIME].refcount == 3, "refcount = %d\n",
*l->locinfo->lc_category[LC_TIME].refcount);
ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n",
@@ -2247,7 +2247,7 @@ static void test__get_current_locale(void)
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n");
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);
+ ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2264,7 +2264,7 @@ static void test__get_current_locale(void)
"same refcount pointers for category %d\n", 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",
+ ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n",
*l2->locinfo->lc_category[i].refcount, i);
}
@@ -2303,7 +2303,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);
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 || broken(l2->locinfo->lc_time_curr->refcount == 2),
+ ok(l2->locinfo->lc_time_curr->refcount == 3 || broken(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 acd58f7a1609..befd0e83d974 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -921,6 +921,27 @@ int CDECL ___lc_collate_cp_func(void)
return get_locinfo()->lc_collate_cp;
}
+/* INTERNAL: increases all reference counts in threadlocinfo struct */
+MSVCRT_pthreadlocinfo grab_locinfo(MSVCRT_pthreadlocinfo locinfo)
+{
+ int i;
+
+ InterlockedIncrement(&locinfo->refcount);
+ for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++)
+ InterlockedIncrement(locinfo->lc_category[i].refcount);
+ if(locinfo->lconv_intl_refcount)
+ InterlockedIncrement(locinfo->lconv_intl_refcount);
+ if(locinfo->lconv_num_refcount)
+ InterlockedIncrement(locinfo->lconv_num_refcount);
+ if(locinfo->lconv_mon_refcount)
+ InterlockedIncrement(locinfo->lconv_mon_refcount);
+ if(locinfo->ctype1_refcount)
+ InterlockedIncrement(locinfo->ctype1_refcount);
+ InterlockedIncrement(&locinfo->lc_time_curr->refcount);
+
+ return locinfo;
+}
+
/* INTERNAL: frees MSVCRT_pthreadlocinfo struct */
void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
{
@@ -929,9 +950,6 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
if(!locinfo)
return;
- if(InterlockedDecrement(&locinfo->refcount))
- return;
-
for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) {
#if _MSVCR_VER >= 110
MSVCRT_free(locinfo->lc_name[i]);
@@ -991,6 +1009,9 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
&& locinfo->lc_time_curr != &cloc_time_data)
MSVCRT_free(locinfo->lc_time_curr);
+ if(InterlockedDecrement(&locinfo->refcount))
+ return;
+
MSVCRT_free(locinfo);
}
@@ -1015,9 +1036,8 @@ MSVCRT__locale_t CDECL MSVCRT__get_current_locale(void)
if(!loc)
return NULL;
- loc->locinfo = get_locinfo();
+ loc->locinfo = grab_locinfo(get_locinfo());
loc->mbcinfo = get_mbcinfo();
- InterlockedIncrement(&loc->locinfo->refcount);
InterlockedIncrement(&loc->mbcinfo->refcount);
return loc;
}
--
2.24.0
More information about the wine-devel
mailing list