From 7ff046219d3a3f3a58b1833e22d3366bcfd32599 Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Mon, 4 Oct 2021 15:11:13 +0200 Subject: [PATCH] Add registerNewResource to handle a diposed resource manager Co-authored-by: Jan Beinke <git@janbeinke.com> --- src/Quasar/ResourceManager.hs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Quasar/ResourceManager.hs b/src/Quasar/ResourceManager.hs index 393bf17..38f4858 100644 --- a/src/Quasar/ResourceManager.hs +++ b/src/Quasar/ResourceManager.hs @@ -2,6 +2,7 @@ module Quasar.ResourceManager ( -- * MonadResourceManager MonadResourceManager(..), FailedToRegisterResource, + registerNewResource, registerDisposable, registerDisposeAction, registerSimpleDisposeAction, @@ -136,6 +137,12 @@ registerDisposeAction disposeAction = mask_ $ registerDisposable =<< newDisposab registerSimpleDisposeAction :: MonadResourceManager m => IO () -> m () registerSimpleDisposeAction disposeAction = registerDisposeAction (pure () <$ disposeAction) +registerNewResource :: (IsDisposable a, MonadResourceManager m) => m a -> m a +registerNewResource action = mask_ do + afix \awaitable -> do + registerDisposeAction $ either (\(_ :: SomeException) -> mempty) dispose =<< try (await awaitable) + action + -- TODO rename to withResourceScope? withSubResourceManagerM :: MonadResourceManager m => m a -> m a @@ -278,20 +285,15 @@ instance IsResourceManager DefaultResourceManager where entry <- newEntry disposable join $ atomically do + disposing <- readTVar (disposingVar resourceManager) disposed <- readTVar (disposedVar resourceManager) - unless disposed $ modifyTVar (entriesVar resourceManager) (|> entry) + unless disposing $ modifyTVar (entriesVar resourceManager) (|> entry) - disposing <- readTVar (disposingVar resourceManager) - - -- IO that is run after the STM transaction is completed - pure $ (`catchAll` throwToResourceManager resourceManager) do - if disposed - then do - traceIO "Attached a disposable to a disposed resource manager" - await =<< dispose disposable - else when disposing do - void (dispose disposable) + pure do + -- IO that is run after the STM transaction is completed + when disposing $ + throwM FailedToRegisterResource `catchAll` throwToResourceManager resourceManager instance IsDisposable DefaultResourceManager where dispose resourceManager = liftIO $ mask_ do @@ -406,6 +408,7 @@ freeGarbage resourceManager = go entriesVar' = entriesVar resourceManager + -- | Creates an `Disposable` that is bound to a ResourceManager. It will automatically be disposed when the resource manager is disposed. attachDisposeAction :: MonadIO m => ResourceManager -> IO (Awaitable ()) -> m Disposable attachDisposeAction resourceManager action = liftIO $ mask_ $ do -- GitLab