Fix concurrency bug that occurred on the first download from an exporttree remote
Block other threads while the export database is being constructed (or updated) by the first thread to try to access it. This work is supported by the NIH-funded NICEMAN (ReproNim TR&D3) project.
This commit is contained in:
parent
fc26fd059b
commit
c24e255de1
3 changed files with 22 additions and 9 deletions
|
@ -19,6 +19,8 @@ git-annex (6.20181012) UNRELEASED; urgency=medium
|
|||
GIT_ANNEX_PACKAGE_INSTALL set. (For Neurodebian packages.)
|
||||
* v6: Fix database inconsistency that could cause git-annex to
|
||||
get confused about whether a locked file's content was present.
|
||||
* Fix concurrency bug that occurred on the first download from an
|
||||
exporttree remote.
|
||||
|
||||
-- Joey Hess <id@joeyh.name> Sat, 13 Oct 2018 00:52:02 -0400
|
||||
|
||||
|
|
|
@ -89,23 +89,32 @@ adjustExportable r = case M.lookup "exporttree" (config r) of
|
|||
}
|
||||
isexport = do
|
||||
db <- openDb (uuid r)
|
||||
updateflag <- liftIO $ newTVarIO Nothing
|
||||
|
||||
updateflag <- liftIO newEmptyTMVarIO
|
||||
let updateonce = liftIO $ atomically $
|
||||
ifM (isEmptyTMVar updateflag)
|
||||
( do
|
||||
putTMVar updateflag ()
|
||||
-- When multiple threads run this, all except the first
|
||||
-- will block until the first runs doneupdateonce.
|
||||
-- Returns True when an update should be done and False
|
||||
-- when the update has already been done.
|
||||
let startupdateonce = liftIO $ atomically $
|
||||
readTVar updateflag >>= \case
|
||||
Nothing -> do
|
||||
writeTVar updateflag (Just True)
|
||||
return True
|
||||
, return False
|
||||
)
|
||||
Just True -> retry
|
||||
Just False -> return False
|
||||
let doneupdateonce = \updated ->
|
||||
when updated $
|
||||
liftIO $ atomically $
|
||||
writeTVar updateflag (Just False)
|
||||
|
||||
-- Get export locations for a key. Checks once
|
||||
-- if the export log is different than the database and
|
||||
-- updates the database, to notice when an export has been
|
||||
-- updated from another repository.
|
||||
let getexportlocs = \k -> do
|
||||
whenM updateonce $
|
||||
updateExportTreeFromLog db
|
||||
bracket startupdateonce doneupdateonce $ \updatenow ->
|
||||
when updatenow $
|
||||
updateExportTreeFromLog db
|
||||
liftIO $ getExportTree db k
|
||||
|
||||
return $ r
|
||||
|
|
|
@ -47,3 +47,5 @@ get sub-01/ses-01/func/sub-01_ses-01_task-Stroop_acq-cf0AP_run-03_physio.tsv.gz
|
|||
|
||||
|
||||
[[!meta author=yoh]]
|
||||
|
||||
> [[fixed|done]] --[[Joey]]
|
||||
|
|
Loading…
Reference in a new issue