ruby-changes:65422
From: Nobuyoshi <ko1@a...>
Date: Mon, 8 Mar 2021 21:01:04 +0900 (JST)
Subject: [ruby-changes:65422] 9299703b39 (master): Make uenvarea thread exclusive
https://git.ruby-lang.org/ruby.git/commit/?id=9299703b39 From 9299703b390a30246819a60516bdd14e37c597fe Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Tue, 23 Feb 2021 20:51:02 +0900 Subject: Make uenvarea thread exclusive --- win32/win32.c | 61 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/win32/win32.c b/win32/win32.c index 83443df..90e109d 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -91,6 +91,7 @@ static char *w32_getenv(const char *name, UINT cp); https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L91 #define dln_find_exe_r(fname, path, buf, size) rb_w32_udln_find_exe_r(fname, path, buf, size, cp) #define dln_find_file_r(fname, path, buf, size) rb_w32_udln_find_file_r(fname, path, buf, size, cp) #undef CharNext /* no default cp version */ +#undef getenv #ifndef PATH_MAX # if defined MAX_PATH @@ -709,6 +710,7 @@ static st_table *conlist = NULL; https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L710 exclusive_for_##obj; \ exclusive_for_##obj = (LeaveCriticalSection(&obj##_mutex), false)) +static CRITICAL_SECTION uenvarea_mutex; static char *uenvarea; /* License: Ruby's */ @@ -750,10 +752,13 @@ exit_handler(void) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L752 DeleteCriticalSection(&select_mutex); DeleteCriticalSection(&socklist_mutex); DeleteCriticalSection(&conlist_mutex); - if (uenvarea) { - free(uenvarea); - uenvarea = NULL; + thread_exclusive(uenvarea) { + if (uenvarea) { + free(uenvarea); + uenvarea = NULL; + } } + DeleteCriticalSection(&uenvarea_mutex); } /* License: Ruby's */ @@ -905,6 +910,7 @@ rb_w32_sysinit(int *argc, char ***argv) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L910 tzset(); + InitializeCriticalSection(&uenvarea_mutex); init_env(); init_stdhandle(); @@ -5261,32 +5267,43 @@ w32_getenv(const char *name, UINT cp) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5267 { WCHAR *wenvarea, *wenv; int len = strlen(name); - char *env; + char *env, *found = NULL; int wlen; if (len == 0) return NULL; - if (uenvarea) { - free(uenvarea); - uenvarea = NULL; - } - wenvarea = GetEnvironmentStringsW(); - if (!wenvarea) { - map_errno(GetLastError()); - return NULL; + if (!NTLoginName) { + /* initialized in init_env, uenvarea_mutex should have been + * initialized before it */ + return getenv(name); } - for (wenv = wenvarea, wlen = 1; *wenv; wenv += lstrlenW(wenv) + 1) - wlen += lstrlenW(wenv) + 1; - uenvarea = wstr_to_mbstr(cp, wenvarea, wlen, NULL); - FreeEnvironmentStringsW(wenvarea); - if (!uenvarea) - return NULL; - for (env = uenvarea; *env; env += strlen(env) + 1) - if (strncasecmp(env, name, len) == 0 && *(env + len) == '=') - return env + len + 1; + thread_exclusive(uenvarea) { + if (uenvarea) { + free(uenvarea); + uenvarea = NULL; + } + wenvarea = GetEnvironmentStringsW(); + if (!wenvarea) { + map_errno(GetLastError()); + continue; + } + for (wenv = wenvarea, wlen = 1; *wenv; wenv += lstrlenW(wenv) + 1) + wlen += lstrlenW(wenv) + 1; + uenvarea = wstr_to_mbstr(cp, wenvarea, wlen, NULL); + FreeEnvironmentStringsW(wenvarea); + if (!uenvarea) + continue; - return NULL; + for (env = uenvarea; *env; env += strlen(env) + 1) { + if (strncasecmp(env, name, len) == 0 && *(env + len) == '=') { + found = env + len + 1; + break; + } + } + } + + return found; } /* License: Ruby's */ -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/