From 0d0fc21e923c1645e860135d4c08490344ba1533 Mon Sep 17 00:00:00 2001
From: Jens Nolte <git@queezle.net>
Date: Wed, 25 Aug 2021 18:37:33 +0200
Subject: [PATCH] Fix (+rewrite) FnDisposable.dispose

---
 src/Quasar/Disposable.hs | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/Quasar/Disposable.hs b/src/Quasar/Disposable.hs
index f33a1d4..d35f01f 100644
--- a/src/Quasar/Disposable.hs
+++ b/src/Quasar/Disposable.hs
@@ -80,13 +80,16 @@ instance IsAwaitable () Disposable where
 newtype FnDisposable = FnDisposable (TMVar (Either (IO (Awaitable ())) (Awaitable ())))
 
 instance IsDisposable FnDisposable where
-  dispose (FnDisposable var) =
-    bracketOnError
-      do atomically $ takeTMVar var
-      do atomically . putTMVar var
-      \case
-        Left action -> do
-          awaitable <- action
+  dispose (FnDisposable var) = do
+    mask \restore -> do
+      eitherVal <- atomically do
+        takeTMVar var >>= \case
+          l@(Left _action) -> pure l
+          -- If the var contains an awaitable its put back immediately to save a second transaction
+          r@(Right _awaitable) -> r <$ putTMVar var r
+      case eitherVal of
+        l@(Left action) -> do
+          awaitable <- restore action `onException` atomically (putTMVar var l)
           atomically $ putTMVar var $ Right awaitable
           pure awaitable
         Right awaitable -> pure awaitable
-- 
GitLab