exclusive locks, ugh

This commit is contained in:
Joey Hess 2011-11-09 22:15:33 -04:00
parent cf0174c922
commit a218ce41cf
2 changed files with 19 additions and 7 deletions

View file

@ -65,8 +65,8 @@ inAnnexSafe = inAnnex' $ \f -> openForLock f False >>= check
is_unlocked = Just True
is_missing = Just False
{- Content is exclusively locked to indicate that it's in the process
- of being removed. (If the content is not present, no locking is done.) -}
{- Content is exclusively locked while running an action that might remove
- it. (If the content is not present, no locking is done.) -}
lockContent :: Key -> Annex a -> Annex a
lockContent key a = do
file <- fromRepo $ gitAnnexLocation key
@ -85,11 +85,14 @@ openForLock file writelock = bracket_ prep cleanup $
(const $ return Nothing)
where
mode = if writelock then ReadWrite else ReadOnly
-- Since files are stored with the write bit disabled,
-- have to fiddle with permissions to open for an
-- exclusive lock.
prep = when writelock $ allowWrite file
cleanup = when writelock $ preventWrite file
{- Since files are stored with the write bit disabled,
- have to fiddle with permissions to open for an
- exclusive lock. flock locking would avoid this,
- but -}
prep = forwritelock $ allowWrite file
cleanup = forwritelock $ preventWrite file
forwritelock a =
when writelock $ whenM (doesFileExist file) $ a
{- Calculates the relative path to use to link a file to a key. -}
calcGitLink :: FilePath -> Key -> Annex FilePath

View file

@ -73,6 +73,15 @@ Another cycle might be running move --to and move --from on the same file,
locally. The exclusivity of the content lock solves this, as only one can
run at a time.
Would it work with a shared lock? The --to would run git-annex-shell
inannex. The --from would also be running, and would run git-annex-shell
dropkey. So inannex and dropkey would end up running on the remote
at the same time. Dropkey takes the content lock, and inannex checks it,
but what if inannex runs first? Then it returns true, and then the content
is removed, so both the --to and --from see success and the --to proceeds
to remove the local content that the --from already caused to be removed
from the remote. So, no, the nasty exclusive lock is needed.
---
Another cycle might involve move --from and drop, both run on the same