TcRnMonad: make forkM thread-safe
authorPatrick Palka <patrick@parcs.ath.cx>
Fri, 23 Aug 2013 01:04:34 +0000 (21:04 -0400)
committerPatrick Palka <patrick@parcs.ath.cx>
Tue, 27 Aug 2013 02:21:16 +0000 (22:21 -0400)
A forkM'd action cannot safely share a UniqSupply with its parent.

[ Originally I resolved this issue in another way: by atomically
  updating env_us in newUnique/newUniqueSupply. But I think this
  (equivalent) change is more sensible. ]

compiler/typecheck/TcRnMonad.lhs

index 84dcecf..1146302 100644 (file)
@@ -1266,7 +1266,11 @@ forkM_maybe :: SDoc -> IfL a -> IfL (Maybe a)
 -- signatures, which is pretty benign
 
 forkM_maybe doc thing_inside
- = do { unsafeInterleaveM $
+ -- NB: Don't share the mutable env_us with the interleaved thread since env_us
+ --     does not get updated atomically (e.g. in newUnique and newUniqueSupply).
+ = do { child_us <- newUniqueSupply
+      ; child_env_us <- newMutVar child_us
+      ; unsafeInterleaveM $ updEnv (\env -> env { env_us = child_env_us }) $
         do { traceIf (text "Starting fork {" <+> doc)
            ; mb_res <- tryM $
                        updLclEnv (\env -> env { if_loc = if_loc env $$ doc }) $