fix STM deadlock in finishCommandActions
Happened every time, because it was taking the pool TMVar while threads were still running, and then the thread would try to switch state.
This commit is contained in:
parent
19321e6892
commit
ad6b8c5f77
2 changed files with 16 additions and 6 deletions
|
@ -129,11 +129,12 @@ finishCommandActions = Annex.getState Annex.workers >>= \case
|
||||||
Nothing -> noop
|
Nothing -> noop
|
||||||
Just tv -> do
|
Just tv -> do
|
||||||
Annex.changeState $ \s -> s { Annex.workers = Nothing }
|
Annex.changeState $ \s -> s { Annex.workers = Nothing }
|
||||||
pool <- liftIO $ atomically $ takeTMVar tv
|
sts <- liftIO $ atomically $ do
|
||||||
forM_ (mapMaybe workerAsync $ workerList pool) $ \aid ->
|
pool <- readTMVar tv
|
||||||
liftIO (waitCatch aid) >>= \case
|
if allIdle pool
|
||||||
Left _ -> noop
|
then return (spareVals pool)
|
||||||
Right st -> mergeState st
|
else retry
|
||||||
|
mapM_ mergeState sts
|
||||||
|
|
||||||
{- Like commandAction, but without the concurrency. -}
|
{- Like commandAction, but without the concurrency. -}
|
||||||
includeCommandAction :: CommandStart -> CommandCleanup
|
includeCommandAction :: CommandStart -> CommandCleanup
|
||||||
|
|
|
@ -17,7 +17,8 @@ data WorkerPool t = WorkerPool
|
||||||
, workerList :: [Worker t]
|
, workerList :: [Worker t]
|
||||||
, spareVals :: [t]
|
, spareVals :: [t]
|
||||||
-- ^ Normally there is one value for each IdleWorker,
|
-- ^ Normally there is one value for each IdleWorker,
|
||||||
-- but there can temporarily be fewer.
|
-- but there can temporarily be fewer values, when a thread is
|
||||||
|
-- changing between stages.
|
||||||
}
|
}
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
|
@ -130,3 +131,11 @@ deactivateWorker pool aid t = pool
|
||||||
| a == aid = IdleWorker st : rest
|
| a == aid = IdleWorker st : rest
|
||||||
| otherwise = w : go rest
|
| otherwise = w : go rest
|
||||||
|
|
||||||
|
allIdle :: WorkerPool t -> Bool
|
||||||
|
allIdle pool = all idle (workerList pool)
|
||||||
|
-- If this does not hold, a thread must be transitioning between
|
||||||
|
-- states, so it's not really idle.
|
||||||
|
&& length (spareVals pool) == length (workerList pool)
|
||||||
|
where
|
||||||
|
idle (IdleWorker _) = True
|
||||||
|
idle (ActiveWorker _ _) = False
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue