diff options
author | Joe Crayne <joe@jerkface.net> | 2020-01-06 21:00:40 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2020-01-06 21:53:25 -0500 |
commit | 3f63b9bcbd5c3871f3a31fa10e4f1e49efea1c39 (patch) | |
tree | d97884b6fddc849c4c7916839328c8a9637f6eec /lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs | |
parent | 25ead19327a58e16fb82f22e20dbe910caf7a2a5 (diff) |
Thread instrumentation: Avoid unlikely leak on race condition.
Diffstat (limited to 'lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs')
-rw-r--r-- | lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs | 17 |
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 | |||
83 | instrumented :: ( HasCallStack, MonadBaseControl IO m ) => | 83 | instrumented :: ( HasCallStack, MonadBaseControl IO m ) => |
84 | (m () -> m ThreadId) -> m () -> m ThreadId | 84 | (m () -> m ThreadId) -> m () -> m ThreadId |
85 | instrumented rawFork action = do | 85 | instrumented 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 | ||
115 | labelThread :: ThreadId -> String -> IO () | 119 | labelThread_ :: ThreadId -> String -> IO () |
116 | labelThread tid s = do | 120 | labelThread_ 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 | |||
128 | labelThread :: ThreadId -> String -> IO () | ||
129 | labelThread 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 | ||
124 | threadsInformation :: IO [(ThreadId,PerThread)] | 135 | threadsInformation :: IO [(ThreadId,PerThread)] |