summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-02-23 20:51:02 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-03-08 17:46:07 +0900
commit9299703b390a30246819a60516bdd14e37c597fe (patch)
tree0a9885468b7e150da35baa8e44bce4694f29aeb2 /win32
parent8c943e3be880eef40023e52daf43d8e0bc8ab59c (diff)
Make uenvarea thread exclusive
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/win32/win32.c b/win32/win32.c
index 83443dfd8b..90e109d5a0 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -91,6 +91,7 @@ static char *w32_getenv(const char *name, UINT cp);
#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;
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)
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)
tzset();
+ InitializeCriticalSection(&uenvarea_mutex);
init_env();
init_stdhandle();
@@ -5261,32 +5267,43 @@ w32_getenv(const char *name, UINT cp)
{
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 */