721cc0cd22
Seems that locking of annexed objects when they're being dropped was broken in direct mode: * When taking the lock before dropping, it created the .git/annex/objects file, as an empty file. It seems that the dropping code deleted that, but that is not right, and for all I know could in some situation cause a corrupted object to leak out. * When the lock was checked, it actually tried to open each direct mode file, and checked if it was locked. Not the same lock used above, and could also fail if some consumer of the file locked it. Fixed this, and added windows support by switching direct mode to lock a .lck file.
50 lines
1.4 KiB
Haskell
50 lines
1.4 KiB
Haskell
{- exception handling in the git-annex monad
|
|
-
|
|
- Note that when an Annex action fails and the exception is handled
|
|
- by these functions, any changes the action has made to the
|
|
- AnnexState are retained. This works because the Annex monad
|
|
- internally stores the AnnexState in a MVar.
|
|
-
|
|
- Copyright 2011-2013 Joey Hess <joey@kitenet.net>
|
|
-
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
-}
|
|
|
|
{-# LANGUAGE PackageImports #-}
|
|
|
|
module Annex.Exception (
|
|
bracketIO,
|
|
bracketAnnex,
|
|
tryAnnex,
|
|
tryAnnexIO,
|
|
throwAnnex,
|
|
catchAnnex,
|
|
) where
|
|
|
|
import qualified "MonadCatchIO-transformers" Control.Monad.CatchIO as M
|
|
import Control.Exception
|
|
|
|
import Common.Annex
|
|
|
|
{- Runs an Annex action, with setup and cleanup both in the IO monad. -}
|
|
bracketIO :: IO v -> (v -> IO b) -> (v -> Annex a) -> Annex a
|
|
bracketIO setup cleanup = M.bracket (liftIO setup) (liftIO . cleanup)
|
|
|
|
bracketAnnex :: Annex v -> (v -> Annex b) -> (v -> Annex a) -> Annex a
|
|
bracketAnnex = M.bracket
|
|
|
|
{- try in the Annex monad -}
|
|
tryAnnex :: Annex a -> Annex (Either SomeException a)
|
|
tryAnnex = M.try
|
|
|
|
{- try in the Annex monad, but only catching IO exceptions -}
|
|
tryAnnexIO :: Annex a -> Annex (Either IOException a)
|
|
tryAnnexIO = M.try
|
|
|
|
{- throw in the Annex monad -}
|
|
throwAnnex :: Exception e => e -> Annex a
|
|
throwAnnex = M.throw
|
|
|
|
{- catch in the Annex monad -}
|
|
catchAnnex :: Exception e => Annex a -> (e -> Annex a) -> Annex a
|
|
catchAnnex = M.catch
|