1- {-# LANGUAGE CPP #-}
2- {-# LANGUAGE DefaultSignatures #-}
3- {-# LANGUAGE MagicHash #-}
4- {-# LANGUAGE PatternSynonyms #-}
5- {-# LANGUAGE TypeFamilies #-}
1+ {-# LANGUAGE CPP #-}
2+ {-# LANGUAGE DefaultSignatures #-}
3+ {-# LANGUAGE FunctionalDependencies #-}
4+ {-# LANGUAGE MagicHash #-}
5+ {-# LANGUAGE PatternSynonyms #-}
6+ {-# LANGUAGE TypeFamilies #-}
67
78module Control.RefCount (
89 -- * Using references
@@ -30,15 +31,12 @@ module Control.RefCount (
3031 , checkForgottenRefs
3132 ) where
3233
33- import Data.Kind (Type )
34- import Data.Primitive.PrimVar
35-
3634import Control.DeepSeq
3735import Control.Exception (assert )
3836import Control.Monad (when )
3937import Control.Monad.Class.MonadThrow
4038import Control.Monad.Primitive
41-
39+ import Data.Primitive.PrimVar
4240import GHC.Stack (CallStack , prettyCallStack )
4341
4442#ifdef NO_IGNORE_ASSERTS
@@ -195,30 +193,36 @@ instance NFData obj => NFData (Ref obj) where
195193-- For objects in this class the guarantee is that (when the 'Ref' rules are
196194-- followed) the object's finaliser is called exactly once.
197195--
198- class RefCounted obj where
199- type FinaliserM obj :: Type -> Type
200- getRefCounter :: obj -> RefCounter (FinaliserM obj )
196+ class RefCounted m obj | obj -> m where
197+ getRefCounter :: obj -> RefCounter m
201198
202199#ifdef NO_IGNORE_ASSERTS
203200#define HasCallStackIfDebug HasCallStack
204201#else
205202#define HasCallStackIfDebug ()
206203#endif
207204
208- -- GHC says specialising is too complicated! But it's ok, each of these can
209- -- inline to calling a few other specialised helpers.
210- {-# INLINE newRef #-}
211- {-# INLINE releaseRef #-}
212- {-# INLINE dupRef #-}
213- {-# INLINE deRefWeak #-}
214-
205+ {-# SPECIALISE
206+ newRef ::
207+ RefCounted IO obj
208+ => IO ()
209+ -> (RefCounter IO -> obj)
210+ -> IO (Ref obj)
211+ #-}
215212-- | Make a new reference.
216213--
217214-- The given finaliser is run when the last reference is released. The
218215-- finaliser is run with async exceptions masked.
219216--
217+ {-# SPECIALISE
218+ newRef ::
219+ RefCounted IO obj
220+ => IO ()
221+ -> (RefCounter IO -> obj)
222+ -> IO (Ref obj)
223+ #-}
220224newRef ::
221- (RefCounted obj , FinaliserM obj ~ m , PrimMonad m )
225+ (RefCounted m obj , PrimMonad m )
222226 => HasCallStackIfDebug
223227 => m ()
224228 -> (RefCounter m -> obj )
@@ -232,8 +236,14 @@ newRef finaliser mkObject = do
232236-- | Release a reference to an object that will no longer be used (via this
233237-- reference).
234238--
239+ {-# SPECIALISE
240+ releaseRef ::
241+ RefCounted IO obj
242+ => Ref obj
243+ -> IO ()
244+ #-}
235245releaseRef ::
236- (RefCounted obj , FinaliserM obj ~ m , PrimMonad m , MonadMask m )
246+ (RefCounted m obj , PrimMonad m , MonadMask m )
237247 => HasCallStackIfDebug
238248 => Ref obj
239249 -> m ()
@@ -261,6 +271,12 @@ deRef ref@Ref{refobj} =
261271 `seq` refobj
262272#endif
263273
274+ {-# SPECIALISE
275+ withRef ::
276+ Ref obj
277+ -> (obj -> IO a)
278+ -> IO a
279+ #-}
264280{-# INLINE withRef #-}
265281-- | Use the object in a 'Ref'. Do not retain the object after the scope of
266282-- the body. If you cannot use scoped \"with\" style, use pattern 'DeRef'.
@@ -276,10 +292,16 @@ withRef ref@Ref{refobj} f = do
276292 assertNoUseAfterRelease ref
277293 f refobj
278294
295+ {-# SPECIALISE
296+ dupRef ::
297+ RefCounted IO obj
298+ => Ref obj
299+ -> IO (Ref obj)
300+ #-}
279301-- | Duplicate an existing reference, to produce a new reference.
280302--
281303dupRef ::
282- (RefCounted obj , FinaliserM obj ~ m , PrimMonad m )
304+ (RefCounted m obj , PrimMonad m )
283305 => HasCallStackIfDebug
284306 => Ref obj
285307 -> m (Ref obj )
@@ -308,11 +330,17 @@ mkWeakRef Ref {refobj} = WeakRef refobj
308330mkWeakRefFromRaw :: obj -> WeakRef obj
309331mkWeakRefFromRaw obj = WeakRef obj
310332
333+ {-# SPECIALISE
334+ deRefWeak ::
335+ RefCounted IO obj
336+ => WeakRef obj
337+ -> IO (Maybe (Ref obj))
338+ #-}
311339-- | If the object is still alive, obtain a /new/ normal reference. The normal
312340-- rules for 'Ref' apply, including the need to eventually call 'releaseRef'.
313341--
314342deRefWeak ::
315- (RefCounted obj , FinaliserM obj ~ m , PrimMonad m )
343+ (RefCounted m obj , PrimMonad m )
316344 => HasCallStackIfDebug
317345 => WeakRef obj
318346 -> m (Maybe (Ref obj ))
0 commit comments