[ruby/tmpdir] [Bug #18933] Make Dir.mktmpdir Ractor-safe

Fix https://bugs.ruby-lang.org/issues/18933

https://github.com/ruby/tmpdir/commit/446e636434
This commit is contained in:
Nobuyoshi Nakada 2022-10-25 12:15:03 +09:00 committed by git
parent 4bfa443383
commit 3e605a7819
2 changed files with 27 additions and 5 deletions

View File

@ -13,15 +13,20 @@ end
class Dir
@@systmpdir ||= defined?(Etc.systmpdir) ? Etc.systmpdir : '/tmp'
# Class variables are inaccessible from non-main Ractor.
# And instance variables too, in Ruby 3.0.
# System-wide temporary directory path
SYSTMPDIR = (defined?(Etc.systmpdir) ? Etc.systmpdir.freeze : '/tmp')
private_constant :SYSTMPDIR
##
# Returns the operating system's temporary file path.
def self.tmpdir
['TMPDIR', 'TMP', 'TEMP', ['system temporary path', @@systmpdir], ['/tmp']*2, ['.']*2].find do |name, dir|
['TMPDIR', 'TMP', 'TEMP', ['system temporary path', SYSTMPDIR], ['/tmp']*2, ['.']*2].find do |name, dir|
unless dir
next if !(dir = ENV[name]) or dir.empty?
next if !(dir = ENV[name] rescue next) or dir.empty?
end
dir = File.expand_path(dir)
stat = File.stat(dir) rescue next
@ -118,16 +123,17 @@ class Dir
UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~"
# Dedicated random number generator
RANDOM = Random.new
RANDOM = Object.new
class << RANDOM # :nodoc:
# Maximum random number
MAX = 36**6 # < 0x100000000
# Returns new random string upto 6 bytes
def next
rand(MAX).to_s(36)
(::Random.urandom(4).unpack1("L")%MAX).to_s(36)
end
end
RANDOM.freeze
private_constant :RANDOM
# Generates and yields random names to create a temporary name

View File

@ -115,4 +115,20 @@ class TestTmpdir < Test::Unit::TestCase
end
end
end
def test_ractor
assert_ractor(<<~'end;', require: "tmpdir")
r = Ractor.new do
Dir.mktmpdir() do |d|
Ractor.yield d
Ractor.receive
end
end
dir = r.take
assert_file.directory? dir
r.send true
r.take
assert_file.not_exist? dir
end;
end
end