From c8c216039a8edb6d4b6de582d6178534ac5b04dc Mon Sep 17 00:00:00 2001
From: Jens Nolte <git@queezle.net>
Date: Thu, 2 Sep 2021 18:16:21 +0200
Subject: [PATCH] Move registerDisposable out of MonadResourceManager

---
 src/Quasar/Disposable.hs | 37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/src/Quasar/Disposable.hs b/src/Quasar/Disposable.hs
index c15bfce..d6128f0 100644
--- a/src/Quasar/Disposable.hs
+++ b/src/Quasar/Disposable.hs
@@ -10,6 +10,8 @@ module Quasar.Disposable (
 
   -- * MonadResourceManager
   MonadResourceManager(..),
+  registerDisposable,
+  registerDisposeAction,
   disposeEventually,
   withOnResourceManager,
   onResourceManager,
@@ -37,7 +39,6 @@ module Quasar.Disposable (
   -- ** Task exceptions
   CancelTask(..),
   TaskDisposed(..),
-
 ) where
 
 import Control.Concurrent (forkIOWithUnmask)
@@ -225,43 +226,43 @@ class IsResourceManager a where
   -- TODO move to class
   --attachDisposable :: (IsDisposable b, MonadIO m) => a -> b -> m ()
 
+  --subResourceManager :: MonadResourceManager m => m (DisposableResourceThingy)
+
+
 instance IsResourceManager ResourceManager where
   toResourceManager = id
 
 class (MonadAwait m, MonadMask m, MonadIO m) => MonadResourceManager m where
-  registerDisposable :: IsDisposable a => a -> m ()
-
-  registerDisposeAction :: IO (Awaitable ()) -> m ()
-  registerDisposeAction disposeAction = mask_ $ registerDisposable =<< newDisposable disposeAction
+  -- | Get the underlying resource manager.
+  askResourceManager :: m ResourceManager
 
+  -- | Replace the resource manager for a computation.
   localResourceManager :: ResourceManager -> m a -> m a
 
-  -- | Get the underlying resource manager. This is intended to fork the Monad (e.g. in the `async`-Function) and must
-  -- not be used to dispose the resource manager (also doing so is a deadlock).
-  --
-  -- Might be replaced with an alternative mechanism in the future.
-  askResourceManager :: m ResourceManager
+
+registerDisposable :: (IsDisposable a, MonadResourceManager m) => a -> m ()
+registerDisposable disposable = do
+  resourceManager <- askResourceManager
+  attachDisposable resourceManager disposable
 
 
-instance (MonadAwait m, MonadMask m, MonadIO m) => MonadResourceManager (ReaderT ResourceManager m) where
-  registerDisposable disposable = do
-    resourceManager <- ask
-    attachDisposable resourceManager disposable
+registerDisposeAction :: MonadResourceManager m => IO (Awaitable ()) -> m ()
+registerDisposeAction disposeAction = mask_ $ registerDisposable =<< newDisposable disposeAction
 
+
+instance (MonadAwait m, MonadMask m, MonadIO m) => MonadResourceManager (ReaderT ResourceManager m) where
   localResourceManager resourceManager = local (const resourceManager)
 
   askResourceManager = ask
 
 
 instance {-# OVERLAPPABLE #-} MonadResourceManager m => MonadResourceManager (ReaderT r m) where
-  registerDisposable disposable = lift $ registerDisposable disposable
+  askResourceManager = lift askResourceManager
 
   localResourceManager resourceManager action = do
     x <- ask
     lift $ localResourceManager resourceManager $ runReaderT action x
 
-  askResourceManager = lift askResourceManager
-
 
 onResourceManager :: (IsResourceManager a) => a -> ReaderT ResourceManager m r -> m r
 onResourceManager target action = runReaderT action (toResourceManager target)
@@ -271,7 +272,7 @@ captureTask :: MonadResourceManager m => m (Awaitable a) -> m (Task a)
 captureTask action = do
   -- TODO improve performance by only creating a new resource manager when two or more disposables are attached
   resourceManager <- newResourceManager
-  awaitable <- localResourceManager resourceManager $ action
+  awaitable <- localResourceManager resourceManager action
   pure $ Task (toDisposable resourceManager) awaitable
 
 captureDisposable :: MonadResourceManager m => m () -> m Disposable
-- 
GitLab