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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to