summaryrefslogtreecommitdiff
path: root/lifted-concurrent
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2020-01-06 21:00:40 -0500
committerJoe Crayne <joe@jerkface.net>2020-01-06 21:53:25 -0500
commit3f63b9bcbd5c3871f3a31fa10e4f1e49efea1c39 (patch)
treed97884b6fddc849c4c7916839328c8a9637f6eec /lifted-concurrent
parent25ead19327a58e16fb82f22e20dbe910caf7a2a5 (diff)
Thread instrumentation: Avoid unlikely leak on race condition.
Diffstat (limited to 'lifted-concurrent')
-rw-r--r--lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs17
1 files changed, 14 insertions, 3 deletions
diff --git a/lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs b/lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs
index afcb81ac..a0bb7dc5 100644
--- a/lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs
+++ b/lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs
@@ -83,6 +83,7 @@ defaultLabel stack = case getCallStack stack of
83instrumented :: ( HasCallStack, MonadBaseControl IO m ) => 83instrumented :: ( HasCallStack, MonadBaseControl IO m ) =>
84 (m () -> m ThreadId) -> m () -> m ThreadId 84 (m () -> m ThreadId) -> m () -> m ThreadId
85instrumented rawFork action = do 85instrumented rawFork action = do
86 mvar <- newEmptyMVar
86 t <- rawFork $ do 87 t <- rawFork $ do
87 tid <- myThreadId 88 tid <- myThreadId
88 tm <- liftBase getCurrentTime 89 tm <- liftBase getCurrentTime
@@ -98,6 +99,7 @@ instrumented rawFork action = do
98 , maybe "" lbl $ Map.lookup tid (threads g) 99 , maybe "" lbl $ Map.lookup tid (threads g)
99 , ")" 100 , ")"
100 ] 101 ]
102 foldr seq (return ()) l
101 putMVar globals $! g { threads = Map.insert tid (PerThread l tm) $ threads g } 103 putMVar globals $! g { threads = Map.insert tid (PerThread l tm) $ threads g }
102 throwIO e) 104 throwIO e)
103 (\g -> do 105 (\g -> do
@@ -108,17 +110,26 @@ instrumented rawFork action = do
108 ] 110 ]
109 reportException g l) 111 reportException g l)
110 -- Remove the thread only if it terminated normally or was killed. 112 -- Remove the thread only if it terminated normally or was killed.
113 takeMVar mvar
111 modifyThreads $! Map.delete tid 114 modifyThreads $! Map.delete tid
112 liftBase $ labelThread t (defaultLabel callStack) 115 liftBase $ labelThread_ t (defaultLabel callStack)
116 putMVar mvar ()
113 return t 117 return t
114 118
115labelThread :: ThreadId -> String -> IO () 119labelThread_ :: ThreadId -> String -> IO ()
116labelThread tid s = do 120labelThread_ tid s = do
121 foldr seq (return ()) s
117 GHC.labelThread tid s 122 GHC.labelThread tid s
118 tm <- liftBase getCurrentTime 123 tm <- liftBase getCurrentTime
119 let updateIt (Just pt) = Just $ pt { lbl = s } 124 let updateIt (Just pt) = Just $ pt { lbl = s }
120 updateIt Nothing = Just $ PerThread s tm 125 updateIt Nothing = Just $ PerThread s tm
121 modifyThreads $! Map.alter updateIt tid 126 modifyThreads $! Map.alter updateIt tid
127
128labelThread :: ThreadId -> String -> IO ()
129labelThread tid s = do
130 foldr seq (return ()) s
131 GHC.labelThread tid s
132 modifyThreads $! Map.adjust (\pt -> pt { lbl = s }) tid
122{-# INLINE labelThread #-} 133{-# INLINE labelThread #-}
123 134
124threadsInformation :: IO [(ThreadId,PerThread)] 135threadsInformation :: IO [(ThreadId,PerThread)]