reorder database shutdown to be concurrency safe
authorJoey Hess <joeyh@joeyh.name>
Wed, 16 Dec 2015 17:52:43 +0000 (13:52 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 16 Dec 2015 17:52:43 +0000 (13:52 -0400)
If a DbHandle is in use by another thread, it could be queueing changes
while shutdown is running. So, wait for the worker to finish before
flushing the queue, so that any last-minute writes are included. Before
this fix, they would be silently dropped.

Of course, if the other thread continues to try to use a DbHandle once it's
closed, it will block forever as the worker is no longer reading from the
jobs MVar. So, that would crash with
"thread blocked indefinitely in an MVar operation".

Database/Handle.hs

index 6d312df685b9232fdf5790655d1a06dc8fdcd7bb..67f7592657c185fc1cf8adfeb4013cbaef70ce95 100644 (file)
@@ -142,9 +142,9 @@ queryDb (DbHandle _ jobs _) a = do
 
 closeDb :: DbHandle -> IO ()
 closeDb h@(DbHandle worker jobs _) = do
-       flushQueueDb h
        putMVar jobs CloseJob
        wait worker
+       flushQueueDb h
 
 type Size = Int