зеркало из https://github.com/github/ruby.git
[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:
Родитель
4bfa443383
Коммит
3e605a7819
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче