Skip to content

Commit

Permalink
cache RandomDevice file from __init__
Browse files Browse the repository at this point in the history
This prevents us from seeing an invalid `IOStream` object from a saved
system image, and also ensures the files are initialized once for all
threads.
  • Loading branch information
JeffBezanson committed Oct 7, 2021
1 parent 7782330 commit 8fdf1aa
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions stdlib/Random/src/RNGs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ else # !windows
rand(rd::RandomDevice, ::SamplerType{Bool}) = read(getfile(rd), UInt8) % Bool

function getfile(rd::RandomDevice)
devrandom = rd.unlimited ? DEV_URANDOM : DEV_RANDOM
# TODO: there is a data-race, this can leak up to nthreads() copies of the file descriptors,
# so use a "thread-once" utility once available
isassigned(devrandom) || (devrandom[] = open(rd.unlimited ? "/dev/urandom" : "/dev/random"))
devrandom[]
devrandom = (rd.unlimited ? DEV_URANDOM : DEV_RANDOM)[]
if devrandom === nothing
error("The requested form of random stream is not available")
end
devrandom
end

const DEV_RANDOM = Ref{IOStream}()
const DEV_URANDOM = Ref{IOStream}()
const DEV_RANDOM = Ref{Union{IOStream,Nothing}}()
const DEV_URANDOM = Ref{Union{IOStream,Nothing}}()

end # os-test

Expand Down Expand Up @@ -411,6 +411,18 @@ for T in BitInteger_types
end

function __init__()
@static if !Sys.iswindows()
DEV_RANDOM[] = try
open("/dev/random")
catch
nothing
end
DEV_URANDOM[] = try
open("/dev/urandom")
catch
nothing
end
end
seed!(GLOBAL_RNG)
end

Expand Down

0 comments on commit 8fdf1aa

Please sign in to comment.