[project @ 2005-01-28 14:55:05 by simonmar]
[ghc-base.git] / GHC / Weak.lhs
index 3ce0467..7179e3d 100644 (file)
@@ -1,5 +1,5 @@
 \begin{code}
-{-# OPTIONS -fno-implicit-prelude #-}
+{-# OPTIONS_GHC -fno-implicit-prelude #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  GHC.Weak
@@ -29,10 +29,16 @@ garbage collector, then the value is also alive.  A reference from
 the value to the key does /not/ keep the key alive.
 
 A weak pointer may also have a finalizer of type @IO ()@; if it does,
-then the finalizer will be run once, and once only, at a time after
-the key has become unreachable by the program (\"dead\").  The storage
-manager attempts to run the finalizer(s) for an object soon after the
-object dies, but promptness is not guaranteed.  
+then the finalizer will be run at most once, at a time after the key
+has become unreachable by the program (\"dead\").  The storage manager
+attempts to run the finalizer(s) for an object soon after the object
+dies, but promptness is not guaranteed.  
+
+It is not guaranteed that a finalizer will eventually run, and no
+attempt is made to run outstanding finalizers when the program exits.
+Therefore finalizers should not be relied on to clean up resources -
+other methods (eg. exception handlers) should be employed, possibly in
+addition to finalisers.
 
 References from the finalizer to the key are treated in the same way
 as references from the value to the key: they do not keep the key
@@ -71,24 +77,27 @@ mkWeak key val Nothing = IO $ \s ->
    case mkWeak# key val (unsafeCoerce# 0#) s of { (# s1, w #) -> (# s1, Weak w #) }
 
 {-|
-  A specialised version of 'mkWeak', where the key and the value are the
-  same object:
-
-  > mkWeakPtr key finalizer = mkWeak key key finalizer
--}
-mkWeakPtr :: k -> Maybe (IO ()) -> IO (Weak k)
-mkWeakPtr key finalizer = mkWeak key key finalizer
+Dereferences a weak pointer.  If the key is still alive, then
+@'Just' v@ is returned (where @v@ is the /value/ in the weak pointer), otherwise
+'Nothing' is returned.
 
-{-|
-  A specialised version of 'mkWeakPtr', where the 'Weak' object
-  returned is simply thrown away (however the finalizer will be
-  remembered by the garbage collector, and will still be run
-  when the key becomes unreachable).
+The return value of 'deRefWeak' depends on when the garbage collector
+runs, hence it is in the 'IO' monad.
 -}
-addFinalizer :: key -> IO () -> IO ()
-addFinalizer key finalizer = do
-   mkWeakPtr key (Just finalizer)      -- throw it away
-   return ()
+deRefWeak :: Weak v -> IO (Maybe v)
+deRefWeak (Weak w) = IO $ \s ->
+   case deRefWeak# w s of
+       (# s1, flag, p #) -> case flag of
+                               0# -> (# s1, Nothing #)
+                               _  -> (# s1, Just p #)
+
+-- | Causes a the finalizer associated with a weak pointer to be run
+-- immediately.
+finalize :: Weak v -> IO ()
+finalize (Weak w) = IO $ \s ->
+   case finalizeWeak# w s of
+       (# s1, 0#, _ #) -> (# s1, () #) -- already dead, or no finaliser
+       (# s1, _,  f #) -> f s1
 
 {-
 Instance Eq (Weak v) where