Skip to content

Commit c99446c

Browse files
committed
STM dirty keys
1 parent 2a35c88 commit c99446c

File tree

2 files changed

+24
-26
lines changed

2 files changed

+24
-26
lines changed

ghcide/src/Development/IDE/Core/FileStore.hs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ module Development.IDE.Core.FileStore(
2424
registerFileWatches
2525
) where
2626

27-
import Control.Concurrent.STM (atomically)
27+
import Control.Concurrent.STM (atomically,
28+
modifyTVar')
2829
import Control.Concurrent.STM.TQueue (writeTQueue)
2930
import Control.Concurrent.Strict
3031
import Control.Exception
@@ -63,7 +64,6 @@ import qualified Development.IDE.Types.Logger as L
6364
import qualified Data.Binary as B
6465
import qualified Data.ByteString.Lazy as LBS
6566
import qualified Data.HashSet as HSet
66-
import Data.IORef.Extra (atomicModifyIORef_)
6767
import Data.List (foldl')
6868
import qualified Data.Text as Text
6969
import Development.IDE.Core.IdeConfiguration (isWorkspaceFile)
@@ -292,9 +292,10 @@ setSomethingModified state keys reason = do
292292
when (isJust setVirtualFileContents) $
293293
fail "setSomethingModified can't be called on this type of VFSHandle"
294294
-- Update database to remove any files that might have been renamed/deleted
295-
atomically $ writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) deleteMissingRealFiles
296-
atomicModifyIORef_ (dirtyKeys $ shakeExtras state) $ \x ->
297-
foldl' (flip HSet.insert) x keys
295+
atomically $ do
296+
writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) deleteMissingRealFiles
297+
modifyTVar' (dirtyKeys $ shakeExtras state) $ \x ->
298+
foldl' (flip HSet.insert) x keys
298299
void $ restartShakeSession (shakeExtras state) reason []
299300

300301
registerFileWatches :: [String] -> LSP.LspT Config IO Bool

ghcide/src/Development/IDE/Core/Shake.hs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,6 @@ import Data.Default
156156
import Data.Foldable (toList)
157157
import Data.HashSet (HashSet)
158158
import qualified Data.HashSet as HSet
159-
import Data.IORef.Extra (atomicModifyIORef'_,
160-
atomicModifyIORef_)
161159
import Data.String (fromString)
162160
import Data.Text (pack)
163161
import Debug.Trace.Flags (userTracingEnabled)
@@ -226,7 +224,7 @@ data ShakeExtras = ShakeExtras
226224
, vfs :: VFSHandle
227225
, defaultConfig :: Config
228226
-- ^ Default HLS config, only relevant if the client does not provide any Config
229-
, dirtyKeys :: IORef (HashSet Key)
227+
, dirtyKeys :: TVar (HashSet Key)
230228
-- ^ Set of dirty rule keys since the last Shake run
231229
}
232230

@@ -440,9 +438,9 @@ deleteValue
440438
-> k
441439
-> NormalizedFilePath
442440
-> IO ()
443-
deleteValue ShakeExtras{dirtyKeys, state} key file = do
444-
atomically $ STM.delete (toKey key file) state
445-
atomicModifyIORef_ dirtyKeys $ HSet.insert (toKey key file)
441+
deleteValue ShakeExtras{dirtyKeys, state} key file = atomically $ do
442+
STM.delete (toKey key file) state
443+
modifyTVar' dirtyKeys $ HSet.insert (toKey key file)
446444

447445
recordDirtyKeys
448446
:: Shake.ShakeValue k
@@ -451,7 +449,7 @@ recordDirtyKeys
451449
-> [NormalizedFilePath]
452450
-> IO ()
453451
recordDirtyKeys ShakeExtras{dirtyKeys} key file = withEventTrace "recordDirtyKeys" $ \addEvent -> do
454-
atomicModifyIORef_ dirtyKeys $ \x -> foldl' (flip HSet.insert) x (toKey key <$> file)
452+
atomically $ modifyTVar' dirtyKeys $ \x -> foldl' (flip HSet.insert) x (toKey key <$> file)
455453
addEvent (fromString $ "dirty " <> show key) (fromString $ unlines $ map fromNormalizedFilePath file)
456454

457455

@@ -538,7 +536,7 @@ shakeOpen lspEnv defaultConfig logger debouncer
538536

539537
let clientCapabilities = maybe def LSP.resClientCapabilities lspEnv
540538

541-
dirtyKeys <- newIORef mempty
539+
dirtyKeys <- newTVarIO mempty
542540
pure ShakeExtras{..}
543541
(shakeDbM, shakeClose) <-
544542
shakeOpenDatabase
@@ -569,7 +567,7 @@ startTelemetry db extras@ShakeExtras{..}
569567
checkParents <- optCheckParents
570568
regularly 1 $ do
571569
observe countKeys . countRelevantKeys checkParents . map fst =<< (atomically . ListT.toList . STM.listT) state
572-
readIORef dirtyKeys >>= observe countDirty . countRelevantKeys checkParents . HSet.toList
570+
readTVarIO dirtyKeys >>= observe countDirty . countRelevantKeys checkParents . HSet.toList
573571
shakeGetBuildStep db >>= observe countBuilds
574572

575573
| otherwise = async (pure ())
@@ -626,7 +624,7 @@ shakeRestart IdeState{..} reason acts =
626624
(\runner -> do
627625
(stopTime,()) <- duration (cancelShakeSession runner)
628626
res <- shakeDatabaseProfile shakeDb
629-
backlog <- readIORef $ dirtyKeys shakeExtras
627+
backlog <- readTVarIO (dirtyKeys shakeExtras)
630628
queue <- atomically $ peekInProgress $ actionQueue shakeExtras
631629
let profile = case res of
632630
Just fp -> ", profile saved at " <> fp
@@ -687,7 +685,7 @@ newSession extras@ShakeExtras{..} shakeDb acts reason = do
687685
reenqueued <- atomically $ peekInProgress actionQueue
688686
allPendingKeys <-
689687
if optRunSubset
690-
then Just <$> readIORef dirtyKeys
688+
then Just <$> readTVarIO dirtyKeys
691689
else return Nothing
692690
let
693691
-- A daemon-like action used to inject additional work
@@ -787,28 +785,27 @@ garbageCollectDirtyKeysOlderThan maxAge checkParents = otTracedGarbageCollection
787785
garbageCollectKeys :: String -> Int -> CheckParents -> [(Key, Int)] -> Action [Key]
788786
garbageCollectKeys label maxAge checkParents agedKeys = do
789787
start <- liftIO offsetTime
790-
extras <- getShakeExtras
791-
let values = state extras
788+
ShakeExtras{state, dirtyKeys, lspEnv, logger, ideTesting} <- getShakeExtras
792789
(n::Int, garbage) <- liftIO $ atomically $
793-
foldM (removeDirtyKey values) (0,[]) agedKeys
794-
liftIO $ atomicModifyIORef_ (dirtyKeys extras) $ \x ->
795-
foldl' (flip HSet.insert) x garbage
790+
foldM (removeDirtyKey dirtyKeys state) (0,[]) agedKeys
796791
t <- liftIO start
797792
when (n>0) $ liftIO $ do
798-
logDebug (logger extras) $ T.pack $
793+
logDebug logger $ T.pack $
799794
label <> " of " <> show n <> " keys (took " <> showDuration t <> ")"
800-
when (coerce $ ideTesting extras) $ liftIO $ mRunLspT (lspEnv extras) $
795+
when (coerce ideTesting) $ liftIO $ mRunLspT lspEnv $
801796
LSP.sendNotification (SCustomMethod "ghcide/GC")
802797
(toJSON $ mapMaybe (fmap showKey . fromKeyType) garbage)
803798
return garbage
804799

805800
where
806801
showKey = show . Q
807-
removeDirtyKey m st@(!counter, keys) (k, age)
802+
removeDirtyKey dk values st@(!counter, keys) (k, age)
808803
| age > maxAge
809804
, Just (kt,_) <- fromKeyType k
810805
, not(kt `HSet.member` preservedKeys checkParents)
811-
= do gotIt <- STM.focus (Focus.member <* Focus.delete) k m
806+
= do gotIt <- STM.focus (Focus.member <* Focus.delete) k values
807+
when gotIt $
808+
modifyTVar' dk (HSet.insert k)
812809
return $ if gotIt then (counter+1, k:keys) else st
813810
| otherwise = pure st
814811

@@ -1063,7 +1060,7 @@ defineEarlyCutoff' doDiagnostics cmp key file old mode action = do
10631060
(if eq then ChangedRecomputeSame else ChangedRecomputeDiff)
10641061
(encodeShakeValue bs) $
10651062
A res
1066-
liftIO $ atomicModifyIORef'_ dirtyKeys (HSet.delete $ toKey key file)
1063+
liftIO $ atomically $ modifyTVar' dirtyKeys (HSet.delete $ toKey key file)
10671064
return res
10681065

10691066
traceA :: A v -> String

0 commit comments

Comments
 (0)