mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Make SecureRandom support Ractor
SecureRandom lazily defines `get_random`. Accessing the mutex to define the `get_random` method is not supported inside a Ractor. This commit defines `gen_random` when `securerandom` is required and makes it suppore Ractor (as well as thread safe). Here is a test program: ```ruby require "securerandom" r = Ractor.new do loop do Ractor.yield SecureRandom.hex end end p r.take ``` Before this commit: ``` $ make runruby ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems ./test.rb <internal:ractor>:38: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. /Users/aaron/git/ruby/lib/securerandom.rb:94:in `gen_random': can not access instance variables of classes/modules from non-main Ractors (RuntimeError) <internal:ractor>:124:in `take': thrown by remote Ractor. (Ractor::RemoteError) from ./test.rb:9:in `<main>' /Users/aaron/git/ruby/lib/securerandom.rb:94:in `gen_random': can not access instance variables of classes/modules from non-main Ractors (RuntimeError) from /Users/aaron/git/ruby/lib/securerandom.rb:155:in `random_bytes' from /Users/aaron/git/ruby/lib/securerandom.rb:176:in `hex' from ./test.rb:5:in `block (2 levels) in <main>' from ./test.rb:4:in `loop' from ./test.rb:4:in `block in <main>' make: *** [runruby] Error ``` After this commit: ``` $ make runruby ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems ./test.rb <internal:ractor>:38: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. "3fc8885157e3911bab4b5d7619bb0308" ```
This commit is contained in:
parent
5001cc4716
commit
475c8701d7
Notes:
git
2020-09-10 04:46:07 +09:00
1 changed files with 15 additions and 31 deletions
|
@ -66,42 +66,11 @@
|
|||
#
|
||||
|
||||
module SecureRandom
|
||||
@rng_chooser = Mutex.new # :nodoc:
|
||||
|
||||
class << self
|
||||
def bytes(n)
|
||||
return gen_random(n)
|
||||
end
|
||||
|
||||
def gen_random(n)
|
||||
ret = Random.urandom(1)
|
||||
if ret.nil?
|
||||
begin
|
||||
require 'openssl'
|
||||
rescue NoMethodError
|
||||
raise NotImplementedError, "No random device"
|
||||
else
|
||||
@rng_chooser.synchronize do
|
||||
class << self
|
||||
remove_method :gen_random
|
||||
alias gen_random gen_random_openssl
|
||||
public :gen_random
|
||||
end
|
||||
end
|
||||
return gen_random(n)
|
||||
end
|
||||
else
|
||||
@rng_chooser.synchronize do
|
||||
class << self
|
||||
remove_method :gen_random
|
||||
alias gen_random gen_random_urandom
|
||||
public :gen_random
|
||||
end
|
||||
end
|
||||
return gen_random(n)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def gen_random_openssl(n)
|
||||
|
@ -129,6 +98,21 @@ module SecureRandom
|
|||
end
|
||||
ret
|
||||
end
|
||||
|
||||
ret = Random.urandom(1)
|
||||
if ret.nil?
|
||||
begin
|
||||
require 'openssl'
|
||||
rescue NoMethodError
|
||||
raise NotImplementedError, "No random device"
|
||||
else
|
||||
alias gen_random gen_random_openssl
|
||||
end
|
||||
else
|
||||
alias gen_random gen_random_urandom
|
||||
end
|
||||
|
||||
public :gen_random
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue