From fe167cbaa50cdbdb74e9818d4110c1aec2c845c7 Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Mon, 9 Aug 2021 01:39:45 +0200 Subject: [PATCH] Add IsDisposable instances for ResourceManager and AsyncTask --- src/Quasar/Core.hs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Quasar/Core.hs b/src/Quasar/Core.hs index 63006d1..2663c6c 100644 --- a/src/Quasar/Core.hs +++ b/src/Quasar/Core.hs @@ -7,11 +7,13 @@ module Quasar.Core ( withDefaultResourceManager, withUnlimitedResourceManager, newResourceManager, - disposeResourceManager, + defaultResourceManagerConfiguration, + unlimitedResourceManagerConfiguration, -- * AsyncTask AsyncTask, cancelTask, + cancelTaskIO, toAsyncTask, successfulTask, @@ -30,6 +32,8 @@ module Quasar.Core ( noDisposable, disposeEventually, boundDisposable, + attachDisposeAction, + attachDisposeAction_, ) where import Control.Concurrent (ThreadId, forkIOWithUnmask, myThreadId) @@ -84,12 +88,14 @@ instance HasResourceManager AsyncIO where awaitResult :: IsAwaitable r a => AsyncIO a -> AsyncIO r awaitResult = (await =<<) --- TODO rename to ResourceManager data ResourceManager = ResourceManager { configuration :: ResourceManagerConfiguraiton, threads :: TVar (HashSet ThreadId) } +instance IsDisposable ResourceManager where + dispose x = pure $ pure () + -- | A task that is running asynchronously. It has a result and can fail. -- The result (or exception) can be aquired by using the `Awaitable` class (e.g. by calling `await` or `awaitIO`). @@ -100,6 +106,9 @@ newtype AsyncTask r = AsyncTask (Awaitable r) instance IsAwaitable r (AsyncTask r) where toAwaitable (AsyncTask awaitable) = awaitable +instance IsDisposable (AsyncTask r) where + dispose = undefined + instance Functor AsyncTask where fmap fn (AsyncTask x) = AsyncTask (fn <$> x) @@ -107,9 +116,11 @@ instance Applicative AsyncTask where pure = AsyncTask . pure liftA2 fn (AsyncTask fx) (AsyncTask fy) = AsyncTask $ liftA2 fn fx fy -cancelTask :: AsyncTask r -> IO () --- TODO resource management -cancelTask = const (pure ()) +cancelTask :: AsyncTask r -> IO (Awaitable ()) +cancelTask = dispose + +cancelTaskIO :: AsyncTask r -> IO () +cancelTaskIO = awaitIO <=< dispose -- | Creates an `AsyncTask` from an `Awaitable`. -- The resulting task only depends on an external resource, so disposing it has no effect. @@ -228,4 +239,12 @@ disposeEventually resourceManager disposable = liftIO $ do -- | Creates an `Disposable` that is bound to a ResourceManager. It will automatically be disposed when the resource manager is disposed. boundDisposable :: HasResourceManager m => IO (Awaitable ()) -> m Disposable -boundDisposable = undefined +boundDisposable action = do + resourceManager <- askResourceManager + attachDisposeAction resourceManager action + +attachDisposeAction :: MonadIO m => ResourceManager -> IO (Awaitable ()) -> m Disposable +attachDisposeAction = undefined + +attachDisposeAction_ :: MonadIO m => ResourceManager -> IO (Awaitable ()) -> m () +attachDisposeAction_ resourceManager action = void $ attachDisposeAction resourceManager action -- GitLab