e213ef310f
* Fix minor FD leak in journal code. Closes: #754608 * direct: Fix handling of case where a work tree subdirectory cannot be written to due to permissions. * migrate: Avoid re-checksumming when migrating from hashE to hash backend. * uninit: Avoid failing final removal in some direct mode repositories due to file modes. * S3: Deal with AWS ACL configurations that do not allow creating or checking the location of a bucket, but only reading and writing content to it. * resolvemerge: New plumbing command that runs the automatic merge conflict resolver. * Deal with change in git 2.0 that made indirect mode merge conflict resolution leave behind old files. * sync: Fix git sync with local git remotes even when they don't have an annex.uuid set. (The assistant already did so.) * Set gcrypt-publish-participants when setting up a gcrypt repository, to avoid unncessary passphrase prompts. This is a security/usability tradeoff. To avoid exposing the gpg key ids who can decrypt the repository, users can unset gcrypt-publish-participants. * Install nautilus hooks even when ~/.local/share/nautilus/ does not yet exist, since it is not automatically created for Gnome 3 users. * Windows: Move .vbs files out of git\bin, to avoid that being in the PATH, which caused some weird breakage. (Thanks, divB) * Windows: Fix locking issue that prevented the webapp starting (since 5.20140707). # imported from the archive
87 lines
2.2 KiB
Haskell
87 lines
2.2 KiB
Haskell
{- git-annex lock files.
|
|
-
|
|
- Copyright 2012, 2014 Joey Hess <joey@kitenet.net>
|
|
-
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
-}
|
|
|
|
{-# LANGUAGE CPP #-}
|
|
|
|
module Annex.LockFile (
|
|
lockFileShared,
|
|
unlockFile,
|
|
getLockPool,
|
|
withExclusiveLock,
|
|
) where
|
|
|
|
import Common.Annex
|
|
import Annex
|
|
import Types.LockPool
|
|
import qualified Git
|
|
import Annex.Exception
|
|
import Annex.Perms
|
|
|
|
import qualified Data.Map as M
|
|
|
|
#ifdef mingw32_HOST_OS
|
|
import Utility.WinLock
|
|
#endif
|
|
|
|
{- Create a specified lock file, and takes a shared lock, which is retained
|
|
- in the pool. -}
|
|
lockFileShared :: FilePath -> Annex ()
|
|
lockFileShared file = go =<< fromLockPool file
|
|
where
|
|
go (Just _) = noop -- already locked
|
|
go Nothing = do
|
|
#ifndef mingw32_HOST_OS
|
|
mode <- annexFileMode
|
|
lockhandle <- liftIO $ noUmask mode $
|
|
openFd file ReadOnly (Just mode) defaultFileFlags
|
|
liftIO $ waitToSetLock lockhandle (ReadLock, AbsoluteSeek, 0, 0)
|
|
#else
|
|
lockhandle <- liftIO $ waitToLock $ lockShared file
|
|
#endif
|
|
changeLockPool $ M.insert file lockhandle
|
|
|
|
unlockFile :: FilePath -> Annex ()
|
|
unlockFile file = maybe noop go =<< fromLockPool file
|
|
where
|
|
go lockhandle = do
|
|
#ifndef mingw32_HOST_OS
|
|
liftIO $ closeFd lockhandle
|
|
#else
|
|
liftIO $ dropLock lockhandle
|
|
#endif
|
|
changeLockPool $ M.delete file
|
|
|
|
getLockPool :: Annex LockPool
|
|
getLockPool = getState lockpool
|
|
|
|
fromLockPool :: FilePath -> Annex (Maybe LockHandle)
|
|
fromLockPool file = M.lookup file <$> getLockPool
|
|
|
|
changeLockPool :: (LockPool -> LockPool) -> Annex ()
|
|
changeLockPool a = do
|
|
m <- getLockPool
|
|
changeState $ \s -> s { lockpool = a m }
|
|
|
|
{- Runs an action with an exclusive lock held. If the lock is already
|
|
- held, blocks until it becomes free. -}
|
|
withExclusiveLock :: (Git.Repo -> FilePath) -> Annex a -> Annex a
|
|
withExclusiveLock getlockfile a = do
|
|
lockfile <- fromRepo getlockfile
|
|
createAnnexDirectory $ takeDirectory lockfile
|
|
mode <- annexFileMode
|
|
bracketIO (lock lockfile mode) unlock (const a)
|
|
where
|
|
#ifndef mingw32_HOST_OS
|
|
lock lockfile mode = do
|
|
l <- noUmask mode $ createFile lockfile mode
|
|
waitToSetLock l (WriteLock, AbsoluteSeek, 0, 0)
|
|
return l
|
|
unlock = closeFd
|
|
#else
|
|
lock lockfile _mode = waitToLock $ lockExclusive lockfile
|
|
unlock = dropLock
|
|
#endif
|