From: Bernhard Übelacker bernhardu@mailbox.org
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55467 --- dlls/msvcrt/locale.c | 22 ++++++++++++++++------ dlls/msvcrt/tests/locale.c | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index f7be2a1e9bc..3bfbddbecfb 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -2034,20 +2034,30 @@ _locale_t CDECL _wcreate_locale(int category, const wchar_t *locale) */ char* CDECL setlocale(int category, const char* locale) { - thread_data_t *data = msvcrt_get_thread_data(); - pthreadlocinfo locinfo = get_locinfo(), newlocinfo; + thread_data_t *data; + pthreadlocinfo locinfo, newlocinfo; + + _lock_locales(); + data = msvcrt_get_thread_data(); + locinfo = get_locinfo();
- if(category<LC_MIN || category>LC_MAX) + if(category<LC_MIN || category>LC_MAX) { + _unlock_locales(); return NULL; + }
if(!locale) { + char* ret; if(category == LC_ALL) - return construct_lc_all(locinfo); - - return locinfo->lc_category[category].locale; + ret = construct_lc_all(locinfo); + else + ret = locinfo->lc_category[category].locale; + _unlock_locales(); + return ret; }
newlocinfo = create_locinfo(category, locale, locinfo); + _unlock_locales(); if(!newlocinfo) { WARN("%d %s failed\n", category, locale); return NULL; diff --git a/dlls/msvcrt/tests/locale.c b/dlls/msvcrt/tests/locale.c index f77e8f93abb..7300ed30803 100644 --- a/dlls/msvcrt/tests/locale.c +++ b/dlls/msvcrt/tests/locale.c @@ -796,6 +796,25 @@ static void test___mb_cur_max_func(void) } }
+static DWORD WINAPI test_setlocale_threads_proc(void *arg) +{ + const char* locale = NULL; + if (*(int*)arg % 2) locale = "German_Germany.1252"; + setlocale(LC_NUMERIC, locale); + return 0; +} + +static void test_setlocale_threads(void) +{ + HANDLE threads[100]; + for (int i = 0; i < ARRAY_SIZE(threads); i++) + { + threads[i] = CreateThread(NULL, 0, test_setlocale_threads_proc, (void*)&i, 0, NULL); + ok(threads[i] != NULL, "CreateThread failed\n"); + } + WaitForMultipleObjects(ARRAY_SIZE(threads), threads, TRUE, INFINITE); +} + START_TEST(locale) { init(); @@ -804,4 +823,5 @@ START_TEST(locale) test_setlocale(); test__Gettnames(); test___mb_cur_max_func(); + test_setlocale_threads(); }