[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]