2014-09-22 13:38:15 +00:00
|
|
|
{-# LANGUAGE DeriveDataTypeable, CPP #-}
|
2014-09-22 12:32:57 +00:00
|
|
|
|
|
|
|
module Misc (
|
2015-08-05 06:52:52 +00:00
|
|
|
SymDbReq
|
2014-09-22 12:32:57 +00:00
|
|
|
, newSymDbReq
|
|
|
|
, getDb
|
|
|
|
, checkDb
|
|
|
|
) where
|
|
|
|
|
|
|
|
import Control.Concurrent.Async (Async, async, wait)
|
|
|
|
import CoreMonad (liftIO)
|
|
|
|
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
|
2015-08-03 01:09:56 +00:00
|
|
|
import Prelude
|
2014-09-22 13:38:15 +00:00
|
|
|
|
2014-09-22 12:32:57 +00:00
|
|
|
import Language.Haskell.GhcMod
|
2015-06-07 18:36:49 +00:00
|
|
|
import Language.Haskell.GhcMod.Internal hiding (MonadIO,liftIO)
|
2014-09-22 12:32:57 +00:00
|
|
|
|
|
|
|
----------------------------------------------------------------
|
|
|
|
|
|
|
|
type SymDbReqAction = (Either GhcModError SymbolDb, GhcModLog)
|
|
|
|
data SymDbReq = SymDbReq (IORef (Async SymDbReqAction)) (IO SymDbReqAction)
|
|
|
|
|
2015-08-14 04:48:56 +00:00
|
|
|
newSymDbReq :: Options -> FilePath -> IO SymDbReq
|
|
|
|
newSymDbReq opt dir = do
|
|
|
|
let act = runGhcModT opt $ loadSymbolDb dir
|
2014-09-22 12:32:57 +00:00
|
|
|
req <- async act
|
|
|
|
ref <- newIORef req
|
|
|
|
return $ SymDbReq ref act
|
|
|
|
|
|
|
|
getDb :: IOish m => SymDbReq -> GhcModT m SymbolDb
|
|
|
|
getDb (SymDbReq ref _) = do
|
|
|
|
req <- liftIO $ readIORef ref
|
|
|
|
-- 'wait' really waits for the asynchronous action at the fist time.
|
|
|
|
-- Then it reads a cached value from the second time.
|
|
|
|
hoistGhcModT =<< liftIO (wait req)
|
|
|
|
|
|
|
|
checkDb :: IOish m => SymDbReq -> SymbolDb -> GhcModT m SymbolDb
|
|
|
|
checkDb (SymDbReq ref act) db = do
|
2015-06-01 12:59:38 +00:00
|
|
|
outdated <- isOutdated db
|
2014-09-22 12:32:57 +00:00
|
|
|
if outdated then do
|
|
|
|
-- async and wait here is unnecessary because this is essentially
|
|
|
|
-- synchronous. But Async can be used a cache.
|
|
|
|
req <- liftIO $ async act
|
|
|
|
liftIO $ writeIORef ref req
|
|
|
|
hoistGhcModT =<< liftIO (wait req)
|
|
|
|
else
|
|
|
|
return db
|