Fix a crash (STM deadlock) when -J is used with multiple files that point to the same key

See the comment for a trace of the deadlock.

Added a new StartStage. New worker threads begin in the StartStage.
Once a thread is ready to do work, it moves away from the StartStage,
and no thread will ever transition back to it.

A thread that blocks waiting on another thread that is processing
the same key will block while in the StartStage. That other thread
will never switch back to the StartStage, and so the deadlock is avoided.
This commit is contained in:
Joey Hess 2019-11-14 11:31:43 -04:00
parent 20d9a9b662
commit 667d38a8f1
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
6 changed files with 114 additions and 24 deletions

View file

@ -63,7 +63,7 @@ commandAction start = Annex.getState Annex.concurrency >>= \case
runconcurrent = Annex.getState Annex.workers >>= \case
Nothing -> runnonconcurrent
Just tv ->
liftIO (atomically (waitInitialWorkerSlot tv)) >>=
liftIO (atomically (waitStartWorkerSlot tv)) >>=
maybe runnonconcurrent (runconcurrent' tv)
runconcurrent' tv (workerst, workerstage) = do
aid <- liftIO $ async $ snd <$> Annex.run workerst
@ -99,12 +99,13 @@ commandAction start = Annex.getState Annex.concurrency >>= \case
case mkActionItem startmsg' of
OnlyActionOn k' _ | k' /= k ->
concurrentjob' workerst startmsg' perform'
_ -> mkjob workerst startmsg' perform'
_ -> beginjob workerst startmsg' perform'
Nothing -> noop
_ -> mkjob workerst startmsg perform
_ -> beginjob workerst startmsg perform
mkjob workerst startmsg perform =
inOwnConsoleRegion (Annex.output workerst) $
beginjob workerst startmsg perform =
inOwnConsoleRegion (Annex.output workerst) $ do
enteringInitialStage
void $ accountCommandAction startmsg $
performconcurrent startmsg perform