Skip to content

Commit f8220ba

Browse files
committed
wait for cancel
1 parent 3bb1e1b commit f8220ba

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

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

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ import qualified StmContainers.Map as STM
174174
import System.FilePath hiding (makeRelative)
175175
import System.IO.Unsafe (unsafePerformIO)
176176
import System.Time.Extra
177+
import Control.Concurrent.Extra (signalBarrier)
177178
-- See Note [Guidelines For Using CPP In GHCIDE Import Statements]
178179

179180
#if !MIN_VERSION_ghc(9,3,0)
@@ -759,31 +760,34 @@ delayedAction a = do
759760
-- Any actions running in the current session will be aborted,
760761
-- but actions added via 'shakeEnqueue' will be requeued.
761762
shakeRestart :: Recorder (WithPriority Log) -> IdeState -> VFSModified -> String -> [DelayedAction ()] -> IO [Key] -> IO ()
762-
shakeRestart recorder IdeState{..} vfs reason acts ioActionBetweenShakeSession =
763+
shakeRestart recorder IdeState{..} vfs reason acts ioActionBetweenShakeSession = do
764+
barrier <- newBarrier
763765
atomically $ writeTQueue (shakeOpQueue $ shakeExtras) $
764-
withMVar'
765-
shakeSession
766-
(\runner -> do
767-
(stopTime,()) <- duration $ logErrorAfter 10 $ cancelShakeSession runner
768-
keys <- ioActionBetweenShakeSession
769-
atomically $ modifyTVar' (dirtyKeys shakeExtras) $ \x -> foldl' (flip insertKeySet) x keys
770-
res <- shakeDatabaseProfile shakeDb
771-
backlog <- readTVarIO $ dirtyKeys shakeExtras
772-
queue <- atomicallyNamed "actionQueue - peek" $ peekInProgress $ actionQueue shakeExtras
773-
774-
-- this log is required by tests
775-
logWith recorder Debug $ LogBuildSessionRestart reason queue backlog stopTime res
776-
)
777-
-- It is crucial to be masked here, otherwise we can get killed
778-
-- between spawning the new thread and updating shakeSession.
779-
-- See https://github.com/haskell/ghcide/issues/79
780-
(\() -> do
781-
(,()) <$> newSession recorder shakeExtras vfs shakeDb acts reason)
782-
where
783-
logErrorAfter :: Seconds -> IO () -> IO ()
784-
logErrorAfter seconds action = flip withAsync (const action) $ do
785-
sleep seconds
786-
logWith recorder Error (LogBuildSessionRestartTakingTooLong seconds)
766+
withMVar'
767+
shakeSession
768+
(\runner -> do
769+
signalBarrier barrier ()
770+
(stopTime,()) <- duration $ logErrorAfter 10 $ cancelShakeSession runner
771+
keys <- ioActionBetweenShakeSession
772+
atomically $ modifyTVar' (dirtyKeys shakeExtras) $ \x -> foldl' (flip insertKeySet) x keys
773+
res <- shakeDatabaseProfile shakeDb
774+
backlog <- readTVarIO $ dirtyKeys shakeExtras
775+
queue <- atomicallyNamed "actionQueue - peek" $ peekInProgress $ actionQueue shakeExtras
776+
777+
-- this log is required by tests
778+
logWith recorder Debug $ LogBuildSessionRestart reason queue backlog stopTime res
779+
)
780+
-- It is crucial to be masked here, otherwise we can get killed
781+
-- between spawning the new thread and updating shakeSession.
782+
-- See https://github.com/haskell/ghcide/issues/79
783+
(\() -> do
784+
(,()) <$> newSession recorder shakeExtras vfs shakeDb acts reason)
785+
waitBarrier barrier
786+
where
787+
logErrorAfter :: Seconds -> IO () -> IO ()
788+
logErrorAfter seconds action = flip withAsync (const action) $ do
789+
sleep seconds
790+
logWith recorder Error (LogBuildSessionRestartTakingTooLong seconds)
787791

788792
-- | Enqueue an action in the existing 'ShakeSession'.
789793
-- Returns a computation to block until the action is run, propagating exceptions.

0 commit comments

Comments
 (0)