Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions ext/etc/etc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1163,14 +1163,27 @@ Init_etc(void)
{
VALUE mEtc;

#ifdef HAVE_RB_EXT_RACTOR_SAFE
RB_EXT_RACTOR_SAFE(true);
#endif
mEtc = rb_define_module("Etc");
/* The version */
rb_define_const(mEtc, "VERSION", rb_str_new_cstr(RUBY_ETC_VERSION));
init_constants(mEtc);

/* Ractor-safe methods */
#ifdef HAVE_RB_EXT_RACTOR_SAFE
RB_EXT_RACTOR_SAFE(true);
#endif
rb_define_module_function(mEtc, "sysconfdir", etc_sysconfdir, 0);
rb_define_module_function(mEtc, "systmpdir", etc_systmpdir, 0);
rb_define_module_function(mEtc, "uname", etc_uname, 0);
rb_define_module_function(mEtc, "sysconf", etc_sysconf, 1);
rb_define_module_function(mEtc, "confstr", etc_confstr, 1);
rb_define_method(rb_cIO, "pathconf", io_pathconf, 1);
rb_define_module_function(mEtc, "nprocessors", etc_nprocessors, 0);

/* Non-Ractor-safe methods, see https://bugs.ruby-lang.org/issues/21115 */
#ifdef HAVE_RB_EXT_RACTOR_SAFE
RB_EXT_RACTOR_SAFE(false);
#endif
rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);

rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1);
Expand All @@ -1186,13 +1199,6 @@ Init_etc(void)
rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0);
rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0);
rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0);
rb_define_module_function(mEtc, "sysconfdir", etc_sysconfdir, 0);
rb_define_module_function(mEtc, "systmpdir", etc_systmpdir, 0);
rb_define_module_function(mEtc, "uname", etc_uname, 0);
rb_define_module_function(mEtc, "sysconf", etc_sysconf, 1);
rb_define_module_function(mEtc, "confstr", etc_confstr, 1);
rb_define_method(rb_cIO, "pathconf", io_pathconf, 1);
rb_define_module_function(mEtc, "nprocessors", etc_nprocessors, 0);

sPasswd = rb_struct_define_under(mEtc, "Passwd",
"name",
Expand Down
58 changes: 57 additions & 1 deletion test/etc/test_etc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,49 @@ def test_sysconfdir
assert_operator(File, :absolute_path?, Etc.sysconfdir)
end if File.method_defined?(:absolute_path?)

def test_ractor
# All Ractor-safe methods should be tested here
def test_ractor_parallel
assert_ractor(<<~RUBY, require: 'etc')
20.times.map do
Ractor.new do
1000.times do
raise unless String === Etc.sysconfdir
raise unless String === Etc.systmpdir
raise unless Hash === Etc.uname
if defined?(Etc::SC_CLK_TCK)
raise unless Integer === Etc.sysconf(Etc::SC_CLK_TCK)
end
if defined?(Etc::CS_PATH)
raise unless String === Etc.confstr(Etc::CS_PATH)
end
if defined?(Etc::PC_PIPE_BUF)
IO.pipe { |r, w|
val = w.pathconf(Etc::PC_PIPE_BUF)
raise unless val.nil? || val.kind_of?(Integer)
}
end
raise unless Integer === Etc.nprocessors
end
end
end.each(&:take)
RUBY
end

def test_ractor_unsafe
assert_ractor(<<~RUBY, require: 'etc')
r = Ractor.new do
begin
Etc.passwd
rescue => e
e.class
end
end.take
assert_equal Ractor::UnsafeError, r
RUBY
end

def test_ractor_passwd
omit("https://bugs.ruby-lang.org/issues/21115")
return unless Etc.passwd # => skip test if no platform support
Etc.endpwent

Expand All @@ -197,4 +239,18 @@ def test_ractor
assert_equal(name2, name)
RUBY
end

def test_ractor_getgrgid
omit("https://bugs.ruby-lang.org/issues/21115")

assert_ractor(<<~RUBY, require: 'etc')
20.times.map do
Ractor.new do
1000.times do
raise unless Etc.getgrgid(Process.gid).gid == Process.gid
end
end
end.each(&:take)
RUBY
end
end