Skip to content

Commit

Permalink
capture error in worker thread (haskell#4342)
Browse files Browse the repository at this point in the history
* use safe try that does not catch the asyncException
  • Loading branch information
soulomoon authored Jul 2, 2024
1 parent 012e809 commit f0ba40b
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions ghcide/src/Development/IDE/Core/WorkerThread.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ module Development.IDE.Core.WorkerThread
(withWorkerQueue, awaitRunInThread)
where

import Control.Concurrent.Async (withAsync)
import Control.Concurrent.Async (AsyncCancelled (AsyncCancelled),
withAsync)
import Control.Concurrent.STM
import Control.Concurrent.Strict (newBarrier, signalBarrier,
waitBarrier)
import Control.Exception.Safe (Exception (fromException),
SomeException, throwIO, try)
import Control.Monad (forever)
import Control.Monad.Cont (ContT (ContT))

Expand Down Expand Up @@ -42,13 +45,15 @@ withWorkerQueue workerAction = ContT $ \mainAction -> do
workerAction l

-- | 'awaitRunInThread' queues up an 'IO' action to be run by a worker thread,
-- and then blocks until the result is computed.
-- and then blocks until the result is computed. If the action throws an
-- non-async exception, it is rethrown in the calling thread.
awaitRunInThread :: TQueue (IO ()) -> IO result -> IO result
awaitRunInThread q act = do
-- Take an action from TQueue, run it and
-- use barrier to wait for the result
barrier <- newBarrier
atomically $ writeTQueue q $ do
res <- act
signalBarrier barrier res
waitBarrier barrier
atomically $ writeTQueue q $ try act >>= signalBarrier barrier
resultOrException <- waitBarrier barrier
case resultOrException of
Left e -> throwIO (e :: SomeException)
Right r -> return r

0 comments on commit f0ba40b

Please sign in to comment.