
Bryan Donlan wrote:
This re-opens the device every time we need it. How about opening once, when it's first needed?
Good idea.
hDevRandom :: Handle {-# NOINLINE hDevRandom #-} hDevRandom = unsafePerformIO $ openFile "/dev/random" ReadMode
hDevURandom :: Handle {-# NOINLINE hDevURandom #-} hDevURandom = unsafePerformIO $ openFile "/dev/urandom" ReadMode
The NOINLINE guarantees that openFile is called only once. But does it guarantee that openFile is NOT called if we do not need it? We could check what the compilers actually do, but I am not sure we have a guarantee here. Perhaps we should do something like data Dev = Dev String (IORef (Maybe Handle)) getDevHandle :: Dev -> IO Handle getDevHandle (Dev path ref) = readIORef ref >>= maybe openDev return where openDev = do h <- openFile path ReadMode writeIORef ref h return h hDevRandom :: Dev {-# NOINLINE hDevRandom #-} hDevRandom = Dev "/dev/random" $ unsafePerformIO $ newIORef Nothing hDevURandom :: Dev {-# NOINLINE hDevURandom #-} hDevURandom = Dev "/dev/urandom" $ unsafePerformIO $ newIORef Nothing -Yitz