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

ruby-changes:70226

From: Rohit <ko1@a...>
Date: Wed, 15 Dec 2021 15:04:58 +0900 (JST)
Subject: [ruby-changes:70226] 2a3e4b6940 (master): Move exception-raising functions out of mutex; Refactor env-copying

https://git.ruby-lang.org/ruby.git/commit/?id=2a3e4b6940

From 2a3e4b69409c8f0f3c63698009f70eefe84a6202 Mon Sep 17 00:00:00 2001
From: Rohit Menon <rohitmenon@v...>
Date: Sat, 3 Jul 2021 14:27:45 -0400
Subject: Move exception-raising functions out of mutex; Refactor env-copying

---
 hash.c | 159 +++++++++++++++++++++++++----------------------------------------
 1 file changed, 61 insertions(+), 98 deletions(-)

diff --git a/hash.c b/hash.c
index e58d21587df..9622663dc5e 100644
--- a/hash.c
+++ b/hash.c
@@ -5194,20 +5194,24 @@ ruby_setenv(const char *name, const char *value) https://github.com/ruby/ruby/blob/trunk/hash.c#L5194
 	invalid_envname(name);
     }
 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
-    rb_native_mutex_lock(&env_lock);
     if (value) {
-	if (setenv(name, value, 1))
+        rb_native_mutex_lock(&env_lock);
+	bool setenv_fail = setenv(name, value, 1);
+	rb_native_mutex_unlock(&env_lock);
+	if (setenv_fail)
 	    rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
     }
     else {
 #ifdef VOID_UNSETENV
 	unsetenv(name);
 #else
-	if (unsetenv(name))
+        rb_native_mutex_lock(&env_lock);
+	bool unsetenv_fail = unsetenv(name);
+	rb_native_mutex_unlock(&env_lock);
+	if (unsetenv_fail)
 	    rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
 #endif
     }
-    rb_native_mutex_unlock(&env_lock);
 #elif defined __sun
     /* Solaris 9 (or earlier) does not have setenv(3C) and unsetenv(3C). */
     /* The below code was tested on Solaris 10 by:
@@ -5234,12 +5238,16 @@ ruby_setenv(const char *name, const char *value) https://github.com/ruby/ruby/blob/trunk/hash.c#L5238
 	}
     }
     if (value) {
-	if (putenv(mem_ptr)) {
+	bool putenv_fail = putenv(mem_ptr);
+	rb_native_mutex_unlock(&env_lock);
+	if (putenv_fail) {
 	    free(mem_ptr);
 	    rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
 	}
     }
-    rb_native_mutex_unlock(&env_lock);
+    else {
+	rb_native_mutex_unlock(&env_lock);
+    }
 #else  /* WIN32 */
     size_t len;
     int i;
@@ -5359,29 +5367,44 @@ env_aset(VALUE nm, VALUE val) https://github.com/ruby/ruby/blob/trunk/hash.c#L5367
     return val;
 }
 
-static VALUE
-env_keys(int raw)
+static int
+env_entry_count()
 {
+    int i;
     char **env;
-    VALUE ary;
-    rb_encoding *enc = raw ? 0 : rb_locale_encoding();
+    env = GET_ENVIRON(environ);
+    for (i=0; env[i]; i++)
+	;
+    FREE_ENVIRON(environ);
+    return i;
+}
 
-    ary = rb_ary_new();
-    rb_native_mutex_lock(&env_lock);
+static void
+copy_env_pairs(VALUE arr[], int size) {
+    char **env;
     env = GET_ENVIRON(environ);
-    int pair_count = 0;
-    while(*(env+pair_count)) {
-	pair_count++;
-    }
-    VALUE env_pairs[pair_count];
-    for(int i = 0; i < pair_count; i++)
+    for(int i = 0; i < size; i++)
     {
 	const char *p = *env;
-	env_pairs[i] = p;
+	arr[i] = p;
 	env++;
     }
     FREE_ENVIRON(environ);
+}
+
+static VALUE
+env_keys(int raw)
+{
+    VALUE ary;
+    rb_encoding *enc = raw ? 0 : rb_locale_encoding();
+
+    ary = rb_ary_new();
+    rb_native_mutex_lock(&env_lock);
+    int pair_count = env_entry_count();
+    VALUE env_pairs[pair_count];
+    copy_env_pairs(env_pairs, pair_count);
     rb_native_mutex_unlock(&env_lock);
+
     for(int current_pair = 0; current_pair < pair_count; current_pair++)
     {
 	const char *p = env_pairs[current_pair];
@@ -5471,20 +5494,11 @@ env_values(void) https://github.com/ruby/ruby/blob/trunk/hash.c#L5494
 
     ary = rb_ary_new();
     rb_native_mutex_lock(&env_lock);
-    env = GET_ENVIRON(environ);
-    int pair_count = 0;
-    while (*(env+pair_count)) {
-	pair_count++;
-    }
+    int pair_count = env_entry_count();
     VALUE env_pairs[pair_count];
-    for(int i = 0; i < pair_count; i++)
-    {
-	const char *p = *env;
-	env_pairs[i] = p;
-	env++;
-    }
-    FREE_ENVIRON(environ);
+    copy_env_pairs(env_pairs, pair_count);
     rb_native_mutex_unlock(&env_lock);
+
     for(int current_pair = 0; current_pair < pair_count; current_pair++)
     {
 	const char *p = env_pairs[current_pair];
@@ -5574,20 +5588,11 @@ env_each_pair(VALUE ehash) https://github.com/ruby/ruby/blob/trunk/hash.c#L5588
 
     ary = rb_ary_new();
     rb_native_mutex_lock(&env_lock);
-    env = GET_ENVIRON(environ);
-    int pair_count = 0;
-    while (*(env+pair_count)) {
-	pair_count++;
-    }
+    int pair_count = env_entry_count();
     VALUE env_pairs[pair_count];
-    for(int i = 0; i < pair_count; i++)
-    {
-	const char *p = *env;
-	env_pairs[i] = p;
-	env++;
-    }
-    FREE_ENVIRON(environ);
+    copy_env_pairs(env_pairs, pair_count);
     rb_native_mutex_unlock(&env_lock);
+
     for(int current_pair = 0; current_pair < pair_count; current_pair++)
     {
 	const char *p = env_pairs[current_pair];
@@ -5941,20 +5946,11 @@ env_inspect(VALUE _) https://github.com/ruby/ruby/blob/trunk/hash.c#L5946
 
     str = rb_str_buf_new2("{");
     rb_native_mutex_lock(&env_lock);
-    env = GET_ENVIRON(environ);
-    int pair_count = 0;
-    while (*(env+pair_count)) {
-	pair_count++;
-    }
+    int pair_count = env_entry_count();
     VALUE env_pairs[pair_count];
-    for(int i = 0; i < pair_count; i++)
-    {
-	const char *p = *env;
-	env_pairs[i] = p;
-	env++;
-    }
-    FREE_ENVIRON(environ);
+    copy_env_pairs(env_pairs, pair_count);
     rb_native_mutex_unlock(&env_lock);
+
     for(int current_pair = 0; current_pair < pair_count; current_pair++)
     {
 	const char *p = env_pairs[current_pair];
@@ -5993,20 +5989,11 @@ env_to_a(VALUE _) https://github.com/ruby/ruby/blob/trunk/hash.c#L5989
 
     ary = rb_ary_new();
     rb_native_mutex_lock(&env_lock);
-    env = GET_ENVIRON(environ);
-    int pair_count = 0;
-    while (*(env+pair_count)) {
-	pair_count++;
-    }
+    int pair_count = env_entry_count();
     VALUE env_pairs[pair_count];
-    for(int i = 0; i < pair_count; i++)
-    {
-	const char *p = *env;
-	env_pairs[i] = p;
-	env++;
-    }
-    FREE_ENVIRON(environ);
+    copy_env_pairs(env_pairs, pair_count);
     rb_native_mutex_unlock(&env_lock);
+
     for(int current_pair = 0; current_pair < pair_count; current_pair++)
     {
 	const char *p = env_pairs[current_pair];
@@ -6046,14 +6033,8 @@ env_none(VALUE _) https://github.com/ruby/ruby/blob/trunk/hash.c#L6033
 static VALUE
 env_size(VALUE _)
 {
-    int i;
-    char **env;
-
     rb_native_mutex_lock(&env_lock);
-    env = GET_ENVIRON(environ);
-    for (i=0; env[i]; i++)
-	;
-    FREE_ENVIRON(environ);
+    int i = env_entry_count();
     rb_native_mutex_unlock(&env_lock);
     return INT2FIX(i);
 }
@@ -6254,20 +6235,11 @@ env_key(VALUE dmy, VALUE value) https://github.com/ruby/ruby/blob/trunk/hash.c#L6235
 
     SafeStringValue(value);
     rb_native_mutex_lock(&env_lock);
-    env = GET_ENVIRON(environ);
-    int pair_count = 0;
-    while (*(env+pair_count)) {
-	pair_count++;
-    }
+    int pair_count = env_entry_count();
     VALUE env_pairs[pair_count];
-    for(int i = 0; i < pair_count; i++)
-    {
-	const char *p = *env;
-	env_pairs[i] = p;
-	env++;
-    }
-    FREE_ENVIRON(environ);
+    copy_env_pairs(env_pairs, pair_count);
     rb_native_mutex_unlock(&env_lock);
+
     for(int current_pair = 0; current_pair < pair_count; current_pair++)
     {
 	const char *p = env_pairs[current_pair];
@@ -6292,20 +6264,11 @@ env_to_hash(void) https://github.com/ruby/ruby/blob/trunk/hash.c#L6264
 
     hash = rb_hash_new();
     rb_native_mutex_lock(&env_lock);
-    env = GET_ENVIRON(environ);
-    int pair_count = 0;
-    while (*(env+pair_count)) {
-	pair_count++;
-    }
+    int pair_count = env_entry_count();
     VALUE env_pairs[pair_count];
-    for(int i = 0; i < pair_count; i++)
-    {
-	const char *p = *env;
-	env_pairs[i] = p;
-	env++;
-    }
-    FREE_ENVIRON(environ);
+    copy_env_pairs(env_pairs, pair_count);
     rb_native_mutex_unlock(&env_lock);
+
     for(int current_pair = 0; current_pair < pair_count; current_pair++)
     {
 	const char *p = env_pairs[current_pair];
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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