Move exception-raising functions out of mutex; Refactor env-copying

This commit is contained in:
Rohit Menon 2021-07-03 14:27:45 -04:00 committed by Koichi Sasada
parent d3d156c21e
commit 2a3e4b6940
Notes: git 2021-12-15 15:05:08 +09:00

159
hash.c
View File

@ -5194,20 +5194,24 @@ ruby_setenv(const char *name, const char *value)
invalid_envname(name); invalid_envname(name);
} }
#elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV) #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
rb_native_mutex_lock(&env_lock);
if (value) { 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)); rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
} }
else { else {
#ifdef VOID_UNSETENV #ifdef VOID_UNSETENV
unsetenv(name); unsetenv(name);
#else #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)); rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
#endif #endif
} }
rb_native_mutex_unlock(&env_lock);
#elif defined __sun #elif defined __sun
/* Solaris 9 (or earlier) does not have setenv(3C) and unsetenv(3C). */ /* Solaris 9 (or earlier) does not have setenv(3C) and unsetenv(3C). */
/* The below code was tested on Solaris 10 by: /* The below code was tested on Solaris 10 by:
@ -5234,12 +5238,16 @@ ruby_setenv(const char *name, const char *value)
} }
} }
if (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); free(mem_ptr);
rb_sys_fail_str(rb_sprintf("putenv(%s)", name)); rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
} }
} }
rb_native_mutex_unlock(&env_lock); else {
rb_native_mutex_unlock(&env_lock);
}
#else /* WIN32 */ #else /* WIN32 */
size_t len; size_t len;
int i; int i;
@ -5359,29 +5367,44 @@ env_aset(VALUE nm, VALUE val)
return val; return val;
} }
static int
env_entry_count()
{
int i;
char **env;
env = GET_ENVIRON(environ);
for (i=0; env[i]; i++)
;
FREE_ENVIRON(environ);
return i;
}
static void
copy_env_pairs(VALUE arr[], int size) {
char **env;
env = GET_ENVIRON(environ);
for(int i = 0; i < size; i++)
{
const char *p = *env;
arr[i] = p;
env++;
}
FREE_ENVIRON(environ);
}
static VALUE static VALUE
env_keys(int raw) env_keys(int raw)
{ {
char **env;
VALUE ary; VALUE ary;
rb_encoding *enc = raw ? 0 : rb_locale_encoding(); rb_encoding *enc = raw ? 0 : rb_locale_encoding();
ary = rb_ary_new(); ary = rb_ary_new();
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int pair_count = env_entry_count();
int pair_count = 0;
while(*(env+pair_count)) {
pair_count++;
}
VALUE env_pairs[pair_count]; VALUE env_pairs[pair_count];
for(int i = 0; i < pair_count; i++) copy_env_pairs(env_pairs, pair_count);
{
const char *p = *env;
env_pairs[i] = p;
env++;
}
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
for(int current_pair = 0; current_pair < pair_count; current_pair++) for(int current_pair = 0; current_pair < pair_count; current_pair++)
{ {
const char *p = env_pairs[current_pair]; const char *p = env_pairs[current_pair];
@ -5471,20 +5494,11 @@ env_values(void)
ary = rb_ary_new(); ary = rb_ary_new();
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int pair_count = env_entry_count();
int pair_count = 0;
while (*(env+pair_count)) {
pair_count++;
}
VALUE env_pairs[pair_count]; VALUE env_pairs[pair_count];
for(int i = 0; i < pair_count; i++) copy_env_pairs(env_pairs, pair_count);
{
const char *p = *env;
env_pairs[i] = p;
env++;
}
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
for(int current_pair = 0; current_pair < pair_count; current_pair++) for(int current_pair = 0; current_pair < pair_count; current_pair++)
{ {
const char *p = env_pairs[current_pair]; const char *p = env_pairs[current_pair];
@ -5574,20 +5588,11 @@ env_each_pair(VALUE ehash)
ary = rb_ary_new(); ary = rb_ary_new();
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int pair_count = env_entry_count();
int pair_count = 0;
while (*(env+pair_count)) {
pair_count++;
}
VALUE env_pairs[pair_count]; VALUE env_pairs[pair_count];
for(int i = 0; i < pair_count; i++) copy_env_pairs(env_pairs, pair_count);
{
const char *p = *env;
env_pairs[i] = p;
env++;
}
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
for(int current_pair = 0; current_pair < pair_count; current_pair++) for(int current_pair = 0; current_pair < pair_count; current_pair++)
{ {
const char *p = env_pairs[current_pair]; const char *p = env_pairs[current_pair];
@ -5941,20 +5946,11 @@ env_inspect(VALUE _)
str = rb_str_buf_new2("{"); str = rb_str_buf_new2("{");
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int pair_count = env_entry_count();
int pair_count = 0;
while (*(env+pair_count)) {
pair_count++;
}
VALUE env_pairs[pair_count]; VALUE env_pairs[pair_count];
for(int i = 0; i < pair_count; i++) copy_env_pairs(env_pairs, pair_count);
{
const char *p = *env;
env_pairs[i] = p;
env++;
}
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
for(int current_pair = 0; current_pair < pair_count; current_pair++) for(int current_pair = 0; current_pair < pair_count; current_pair++)
{ {
const char *p = env_pairs[current_pair]; const char *p = env_pairs[current_pair];
@ -5993,20 +5989,11 @@ env_to_a(VALUE _)
ary = rb_ary_new(); ary = rb_ary_new();
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int pair_count = env_entry_count();
int pair_count = 0;
while (*(env+pair_count)) {
pair_count++;
}
VALUE env_pairs[pair_count]; VALUE env_pairs[pair_count];
for(int i = 0; i < pair_count; i++) copy_env_pairs(env_pairs, pair_count);
{
const char *p = *env;
env_pairs[i] = p;
env++;
}
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
for(int current_pair = 0; current_pair < pair_count; current_pair++) for(int current_pair = 0; current_pair < pair_count; current_pair++)
{ {
const char *p = env_pairs[current_pair]; const char *p = env_pairs[current_pair];
@ -6046,14 +6033,8 @@ env_none(VALUE _)
static VALUE static VALUE
env_size(VALUE _) env_size(VALUE _)
{ {
int i;
char **env;
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int i = env_entry_count();
for (i=0; env[i]; i++)
;
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
return INT2FIX(i); return INT2FIX(i);
} }
@ -6254,20 +6235,11 @@ env_key(VALUE dmy, VALUE value)
SafeStringValue(value); SafeStringValue(value);
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int pair_count = env_entry_count();
int pair_count = 0;
while (*(env+pair_count)) {
pair_count++;
}
VALUE env_pairs[pair_count]; VALUE env_pairs[pair_count];
for(int i = 0; i < pair_count; i++) copy_env_pairs(env_pairs, pair_count);
{
const char *p = *env;
env_pairs[i] = p;
env++;
}
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
for(int current_pair = 0; current_pair < pair_count; current_pair++) for(int current_pair = 0; current_pair < pair_count; current_pair++)
{ {
const char *p = env_pairs[current_pair]; const char *p = env_pairs[current_pair];
@ -6292,20 +6264,11 @@ env_to_hash(void)
hash = rb_hash_new(); hash = rb_hash_new();
rb_native_mutex_lock(&env_lock); rb_native_mutex_lock(&env_lock);
env = GET_ENVIRON(environ); int pair_count = env_entry_count();
int pair_count = 0;
while (*(env+pair_count)) {
pair_count++;
}
VALUE env_pairs[pair_count]; VALUE env_pairs[pair_count];
for(int i = 0; i < pair_count; i++) copy_env_pairs(env_pairs, pair_count);
{
const char *p = *env;
env_pairs[i] = p;
env++;
}
FREE_ENVIRON(environ);
rb_native_mutex_unlock(&env_lock); rb_native_mutex_unlock(&env_lock);
for(int current_pair = 0; current_pair < pair_count; current_pair++) for(int current_pair = 0; current_pair < pair_count; current_pair++)
{ {
const char *p = env_pairs[current_pair]; const char *p = env_pairs[current_pair];