Use atomicModifyIORef instead of readIORef.

<http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-IORef.html#g:2>
This commit is contained in:
Felipe Lessa 2015-05-27 23:21:23 -03:00
parent 060187f997
commit adf97f5d07
2 changed files with 9 additions and 3 deletions

View File

@ -60,7 +60,7 @@ sessionStore state =
(sessionMap, saveSessionToken) <- loadSession state mcookieVal
sessionRef <- I.newIORef sessionMap
let save = do
sessionMap' <- I.readIORef sessionRef
sessionMap' <- I.atomicModifyIORef' sessionRef $ \a -> (a, a)
session <- saveSession state saveSessionToken sessionMap'
return $ TE.encodeUtf8 $ toPathPiece $ sessionKey session
return (mkSession sessionRef, save)
@ -70,7 +70,10 @@ sessionStore state =
-- session data.
mkSession :: MonadIO m => I.IORef SessionMap -> WS.Session m Text ByteString
mkSession sessionRef =
( \k -> M.lookup k <$> liftIO (I.readIORef sessionRef)
-- We need to use atomicModifyIORef instead of readIORef
-- because latter may be reordered (cf. "Memory Model" on
-- Data.IORef's documentation).
( \k -> M.lookup k <$> liftIO (I.atomicModifyIORef' sessionRef $ \a -> (a, a))
, \k v -> liftIO (I.atomicModifyIORef' sessionRef $ flip (,) () . M.insert k v)
)

View File

@ -286,7 +286,10 @@ instance Storage MockStorage where
type TransactionM MockStorage = IO
runTransactionM _ = id
getSession sto sid =
M.lookup sid <$> I.readIORef (mockSessions sto)
-- We need to use atomicModifyIORef instead of readIORef
-- because latter may be reordered (cf. "Memory Model" on
-- Data.IORef's documentation).
M.lookup sid <$> I.atomicModifyIORef' (mockSessions sto) (\a -> (a, a))
deleteSession sto sid =
I.modifyIORef (mockSessions sto) (M.delete sid)
deleteAllSessionsOfAuthId sto authId =