{-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} {- | Maintainer: simons@cryp.to Stability: provisional Portability: portable Low-level bindings to OpenSSL's EVP interface. Most users do not need this code. Check out "OpenSSL.Digest" for a more comfortable interface. -} module OpenSSL.EVP.Digest.Initialization ( initializeEVPDigests ) where import Control.Concurrent.MVar import Control.Monad import System.IO.Unsafe as IO #include "openssl/opensslv.h" -- | Initialize the OpenSSL EVP engine and register all known digest types in -- the internal data structures. This function must be called before any of the -- message digest functions can succeed. This is generally handled -- transparently by the Haskell implementation and users do not need to worry -- about this. initializeEVPDigests :: IO () initializeEVPDigests = #if OPENSSL_VERSION_NUMBER >= 0x1010000f return () #else modifyMVar_ isDigestEngineInitialized $ \isInitialized -> unless isInitialized _addAllDigests >> return True {-# NOINLINE isDigestEngineInitialized #-} isDigestEngineInitialized :: MVar Bool isDigestEngineInitialized = IO.unsafePerformIO $ newMVar False foreign import ccall unsafe "openssl/evp.h OpenSSL_add_all_digests" _addAllDigests :: IO () #endif