@@ -7,19 +7,21 @@ type Map = Map.Map
77{- ----------------------------------------------------------------------------
88 Locker
99------------------------------------------------------------------------------}
10- data Key s a = Key ! Unique (IORef (Maybe a ))
10+ data Key s a = Key ! Unique (IORef (Maybe a )) ( MVar () )
1111data Locker s = Locker ! Unique (IO () )
1212
1313#if IsStrict
14- lock (Key u ref) x = x `seq` (Locker u $ writeIORef ref $ Just x)
14+ lock (Key u ref _ ) x = x `seq` (Locker u $ writeIORef ref $ Just x)
1515#else
16- lock (Key u ref) x = Locker u $ writeIORef ref $ Just x
16+ lock (Key u ref _ ) x = Locker u $ writeIORef ref $ Just x
1717#endif
1818
19- unlock (Key k ref) (Locker k' m)
19+ unlock (Key k ref lock ) (Locker k' m)
2020 | k == k' = unsafePerformIO $ do
21+ takeMVar lock
2122 m
22- readIORef ref -- FIXME: race condition!
23+ readIORef ref
24+ putMVar lock ()
2325 | otherwise = Nothing
2426
2527{- ----------------------------------------------------------------------------
@@ -28,13 +30,13 @@ unlock (Key k ref) (Locker k' m)
2830-- implemented as a collection of lockers
2931newtype Vault s = Vault (Map Unique (Locker s ))
3032
31- newKey = unsafeIOToST $ Key <$> newUnique <*> newIORef Nothing
33+ newKey = unsafeIOToST $ Key <$> newUnique <*> newIORef Nothing <*> newMVar ()
3234
33- lookup key@ (Key k _) (Vault m) = unlock key =<< Map. lookup k m
35+ lookup key@ (Key k _ _ ) (Vault m) = unlock key =<< Map. lookup k m
3436
35- insert key@ (Key k _) x (Vault m) = Vault $ Map. insert k (lock key x) m
37+ insert key@ (Key k _ _ ) x (Vault m) = Vault $ Map. insert k (lock key x) m
3638
37- adjust f key@ (Key k _) (Vault m) = Vault $ Map. update f' k m
39+ adjust f key@ (Key k _ _ ) (Vault m) = Vault $ Map. update f' k m
3840 where f' = fmap (lock key . f) . unlock key
3941
40- delete (Key k _) (Vault m) = Vault $ Map. delete k m
42+ delete (Key k _ _ ) (Vault m) = Vault $ Map. delete k m
0 commit comments