generalize and improve state MVar code
This commit is contained in:
parent
5308b51ec0
commit
e5f855b7f8
1 changed files with 28 additions and 20 deletions
|
@ -24,7 +24,6 @@ import qualified Git.UpdateIndex
|
||||||
import qualified Backend
|
import qualified Backend
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
|
|
||||||
import Control.Exception as E
|
|
||||||
import Control.Concurrent.MVar
|
import Control.Concurrent.MVar
|
||||||
|
|
||||||
#if defined linux_HOST_OS
|
#if defined linux_HOST_OS
|
||||||
|
@ -43,10 +42,8 @@ start = notBareRepo $ do
|
||||||
showStart "watch" "."
|
showStart "watch" "."
|
||||||
showAction "scanning"
|
showAction "scanning"
|
||||||
inRepo $ Git.Command.run "add" [Param "--update"]
|
inRepo $ Git.Command.run "add" [Param "--update"]
|
||||||
state <- Annex.getState id
|
next $ next $ withStateMVar $ \mvar -> liftIO $ withINotify $ \i -> do
|
||||||
mvar <- liftIO $ newMVar state
|
let hook a = Just $ runHook mvar a
|
||||||
next $ next $ liftIO $ withINotify $ \i -> do
|
|
||||||
let hook a = Just $ runAnnex mvar a
|
|
||||||
let hooks = WatchHooks
|
let hooks = WatchHooks
|
||||||
{ addHook = hook onAdd
|
{ addHook = hook onAdd
|
||||||
, delHook = hook onDel
|
, delHook = hook onDel
|
||||||
|
@ -68,23 +65,36 @@ ignored ".gitignore" = True
|
||||||
ignored ".gitattributes" = True
|
ignored ".gitattributes" = True
|
||||||
ignored _ = False
|
ignored _ = False
|
||||||
|
|
||||||
{- Runs a handler, inside the Annex monad.
|
{- Stores the Annex state in a MVar, so that threaded actions can access
|
||||||
|
- it.
|
||||||
-
|
-
|
||||||
- Exceptions by the handlers are ignored, otherwise a whole watcher
|
- Once the action is finished, retrieves the state from the MVar.
|
||||||
- thread could be crashed.
|
|
||||||
-}
|
-}
|
||||||
runAnnex :: MVar Annex.AnnexState -> (FilePath -> Annex a) -> FilePath -> IO ()
|
withStateMVar :: (MVar Annex.AnnexState -> Annex a) -> Annex a
|
||||||
runAnnex mvar a f = do
|
withStateMVar a = do
|
||||||
|
state <- Annex.getState id
|
||||||
|
mvar <- liftIO $ newMVar state
|
||||||
|
r <- a mvar
|
||||||
|
newstate <- liftIO $ takeMVar mvar
|
||||||
|
Annex.changeState (const newstate)
|
||||||
|
return r
|
||||||
|
|
||||||
|
{- Runs an Annex action, using the state from the MVar. -}
|
||||||
|
runStateMVar :: MVar Annex.AnnexState -> Annex () -> IO ()
|
||||||
|
runStateMVar mvar a = do
|
||||||
startstate <- takeMVar mvar
|
startstate <- takeMVar mvar
|
||||||
r <- E.try (go startstate) :: IO (Either E.SomeException Annex.AnnexState)
|
!newstate <- Annex.exec startstate a
|
||||||
case r of
|
putMVar mvar newstate
|
||||||
Left e -> do
|
|
||||||
putStrLn (show e)
|
{- Runs a hook, inside the Annex monad.
|
||||||
putMVar mvar startstate
|
-
|
||||||
Right !newstate ->
|
- Exceptions are ignored, otherwise a whole watcher thread could be crashed.
|
||||||
putMVar mvar newstate
|
-}
|
||||||
|
runHook :: MVar Annex.AnnexState -> (FilePath -> Annex ()) -> FilePath -> IO ()
|
||||||
|
runHook mvar a f = handle =<< tryIO (runStateMVar mvar $ a f)
|
||||||
where
|
where
|
||||||
go state = Annex.exec state $ a f
|
handle (Right ()) = return ()
|
||||||
|
handle (Left e) = putStrLn $ show e
|
||||||
|
|
||||||
{- Adding a file is tricky; the file has to be replaced with a symlink
|
{- Adding a file is tricky; the file has to be replaced with a symlink
|
||||||
- but this is race prone, as the symlink could be changed immediately
|
- but this is race prone, as the symlink could be changed immediately
|
||||||
|
@ -120,8 +130,6 @@ onAddSymlink file = go =<< Backend.lookupFile file
|
||||||
)
|
)
|
||||||
addlink link = stageSymlink file link
|
addlink link = stageSymlink file link
|
||||||
|
|
||||||
{- The file could reappear at any time, so --cached is used, to only delete
|
|
||||||
- it from the index. -}
|
|
||||||
onDel :: FilePath -> Annex ()
|
onDel :: FilePath -> Annex ()
|
||||||
onDel file = Annex.Queue.addUpdateIndex =<<
|
onDel file = Annex.Queue.addUpdateIndex =<<
|
||||||
inRepo (Git.UpdateIndex.unstageFile file)
|
inRepo (Git.UpdateIndex.unstageFile file)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue