aboutsummaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorRohit Menon <rohitmenon@verizon.net>2021-07-03 14:27:45 -0400
committerKoichi Sasada <ko1@atdot.net>2021-12-15 15:04:34 +0900
commit2a3e4b69409c8f0f3c63698009f70eefe84a6202 (patch)
treeb6eb6de3b0ef38c5ae22318eeb08650213d24e72 /hash.c
parentd3d156c21ecf0a602d366209b3e2da665c3ec389 (diff)
downloadruby-2a3e4b69409c8f0f3c63698009f70eefe84a6202.tar.gz
Move exception-raising functions out of mutex; Refactor env-copying
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c159
1 files changed, 61 insertions, 98 deletions
diff --git a/hash.c b/hash.c
index e58d21587d..9622663dc5 100644
--- a/hash.c
+++ b/hash.c
@@ -5194,20 +5194,24 @@ ruby_setenv(const char *name, const char *value)
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)
}
}
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)
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)
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)
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 _)
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 _)
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 _)
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)
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)
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];