create global oigInc instance

Before if multiple threads instantiated their own ObjectIdGen
structure it would be possible to get duplicate objectid's
generated. By making sure there is a single inc counter, this is
avoided.
This commit is contained in:
Scott R. Parish 2010-03-13 20:46:57 -06:00
parent 66cbae9046
commit 3956adab00

View file

@ -37,7 +37,7 @@ module Database.MongoDB.BSON
-- * Binary encoding/decoding -- * Binary encoding/decoding
getBsonDoc, putBsonDoc, getBsonDoc, putBsonDoc,
-- * ObjectId creation -- * ObjectId creation
mkObjectIdGen, genObjectId, ObjectIdGen, mkObjectIdGen, genObjectId,
) )
where where
import Prelude hiding (lookup) import Prelude hiding (lookup)
@ -64,6 +64,7 @@ import Data.Typeable
import Database.MongoDB.Util import Database.MongoDB.Util
import Network.BSD import Network.BSD
import Numeric import Numeric
import System.IO.Unsafe
import System.Posix.Process import System.Posix.Process
-- | BsonValue is the type that can be used as a key in a 'BsonDoc'. -- | BsonValue is the type that can be used as a key in a 'BsonDoc'.
@ -150,12 +151,15 @@ data ObjectIdGen = ObjectIdGen {
oigInc :: IORef Integer oigInc :: IORef Integer
} }
globalObjectIdInc :: IORef Integer
{-# NOINLINE globalObjectIdInc #-}
globalObjectIdInc = unsafePerformIO (newIORef 0)
mkObjectIdGen :: IO ObjectIdGen mkObjectIdGen :: IO ObjectIdGen
mkObjectIdGen = do mkObjectIdGen = do
host <- liftM (fst . (!! 0) . readHex . List.take 6 . md5sum . C8.pack) host <- liftM (fst . (!! 0) . readHex . List.take 6 . md5sum . C8.pack)
getHostName getHostName
inc <- newIORef 0 return ObjectIdGen {oigMachine = host, oigInc = globalObjectIdInc}
return ObjectIdGen {oigMachine = host, oigInc = inc}
genObjectId :: ObjectIdGen -> IO BsonValue genObjectId :: ObjectIdGen -> IO BsonValue
genObjectId oig = do genObjectId oig = do