[ruby/etc] Refactor locks using mutex API

This commit is contained in:
Marc-Andre Lafortune 2020-12-22 00:02:45 -05:00 committed by Marc-André Lafortune
parent 9636d14f6f
commit 3286380ebc
Notes: git 2020-12-23 09:46:33 +09:00

View File

@ -62,6 +62,19 @@ void rb_deprecate_constant(VALUE mod, const char *name);
#include "constdefs.h" #include "constdefs.h"
typedef int rb_nativethread_lock_t;
static int rb_native_mutex_trylock(int *mutex) {
if (*mutex) {
return 1;
}
*mutex = 1;
return 0;
}
static void rb_native_mutex_unlock(int *mutex) {
*mutex = 0;
}
#define rb_native_mutex_initialize rb_native_mutex_unlock
/* call-seq: /* call-seq:
* getlogin -> String * getlogin -> String
* *
@ -240,12 +253,12 @@ etc_getpwnam(VALUE obj, VALUE nam)
} }
#ifdef HAVE_GETPWENT #ifdef HAVE_GETPWENT
static int passwd_blocking = 0; static rb_nativethread_lock_t passwd_blocking;
static VALUE static VALUE
passwd_ensure(VALUE _) passwd_ensure(VALUE _)
{ {
endpwent(); endpwent();
passwd_blocking = (int)Qfalse; rb_native_mutex_unlock(&passwd_blocking);
return Qnil; return Qnil;
} }
@ -264,10 +277,9 @@ passwd_iterate(VALUE _)
static void static void
each_passwd(void) each_passwd(void)
{ {
if (passwd_blocking) { if (rb_native_mutex_trylock(&passwd_blocking)) {
rb_raise(rb_eRuntimeError, "parallel passwd iteration"); rb_raise(rb_eRuntimeError, "parallel passwd iteration");
} }
passwd_blocking = (int)Qtrue;
rb_ensure(passwd_iterate, 0, passwd_ensure, 0); rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
} }
#endif #endif
@ -483,12 +495,12 @@ etc_getgrnam(VALUE obj, VALUE nam)
} }
#ifdef HAVE_GETGRENT #ifdef HAVE_GETGRENT
static int group_blocking = 0; static rb_nativethread_lock_t group_blocking;
static VALUE static VALUE
group_ensure(VALUE _) group_ensure(VALUE _)
{ {
endgrent(); endgrent();
group_blocking = (int)Qfalse; rb_native_mutex_unlock(&group_blocking);
return Qnil; return Qnil;
} }
@ -508,10 +520,9 @@ group_iterate(VALUE _)
static void static void
each_group(void) each_group(void)
{ {
if (group_blocking) { if (rb_native_mutex_trylock(&group_blocking)) {
rb_raise(rb_eRuntimeError, "parallel group iteration"); rb_raise(rb_eRuntimeError, "parallel group iteration");
} }
group_blocking = (int)Qtrue;
rb_ensure(group_iterate, 0, group_ensure, 0); rb_ensure(group_iterate, 0, group_ensure, 0);
} }
#endif #endif
@ -1180,8 +1191,11 @@ Init_etc(void)
rb_deprecate_constant(rb_cStruct, "Passwd"); rb_deprecate_constant(rb_cStruct, "Passwd");
rb_extend_object(sPasswd, rb_mEnumerable); rb_extend_object(sPasswd, rb_mEnumerable);
rb_define_singleton_method(sPasswd, "each", etc_each_passwd, 0); rb_define_singleton_method(sPasswd, "each", etc_each_passwd, 0);
#ifdef HAVE_GETPWENT
rb_native_mutex_initialize(&passwd_blocking);
#endif
#ifdef HAVE_GETGRENT #ifdef HAVE_GETGRENT
rb_native_mutex_initialize(&group_blocking);
sGroup = rb_struct_define_under(mEtc, "Group", "name", sGroup = rb_struct_define_under(mEtc, "Group", "name",
#ifdef HAVE_STRUCT_GROUP_GR_PASSWD #ifdef HAVE_STRUCT_GROUP_GR_PASSWD
"passwd", "passwd",