fix MVar deadlock when sqlite commit fails

The database queue was left empty, which caused subsequent calls to
flushDbQueue to deadlock.

Sponsored-by: Dartmouth College's Datalad project
This commit is contained in:
Joey Hess 2022-06-06 12:16:55 -04:00
parent 7851d8fb42
commit 331c97df88
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 29 additions and 4 deletions

View file

@ -1,6 +1,6 @@
{- Persistent sqlite database queues
-
- Copyright 2015 Joey Hess <id@joeyh.name>
- Copyright 2015-2022 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
@ -20,6 +20,7 @@ module Database.Queue (
import Utility.Monad
import Utility.RawFilePath
import Utility.DebugLocks
import Utility.Exception
import Database.Handle
import Database.Persist.Sqlite
@ -54,9 +55,11 @@ flushDbQueue :: DbQueue -> IO ()
flushDbQueue (DQ hdl qvar) = do
q@(Queue sz _ qa) <- debugLocks $ takeMVar qvar
if sz > 0
then do
commitDb hdl qa
debugLocks $ putMVar qvar =<< emptyQueue
then tryNonAsync (commitDb hdl qa) >>= \case
Right () -> debugLocks $ putMVar qvar =<< emptyQueue
Left e -> do
debugLocks $ putMVar qvar q
throwM e
else debugLocks $ putMVar qvar q
{- Makes a query using the DbQueue's database connection.