From ba28da170ff23b4eacd3cd07135581c7ad7fb347 Mon Sep 17 00:00:00 2001 From: simonm Date: Thu, 11 Feb 1999 17:56:49 +0000 Subject: [PATCH] [project @ 1999-02-11 17:56:49 by simonm] Weak library updates. --- ghc/docs/libraries/Weak.sgml | 122 ++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 69 deletions(-) diff --git a/ghc/docs/libraries/Weak.sgml b/ghc/docs/libraries/Weak.sgml index 80ba68b..68f5028 100644 --- a/ghc/docs/libraries/Weak.sgml +++ b/ghc/docs/libraries/Weak.sgml @@ -4,7 +4,7 @@ The v -> IO () -> IO (Weak v) + mkWeak, -- :: k -> v -> Maybe (IO ()) -> IO (Weak v) deRefWeak, -- :: Weak v -> IO (Maybe v) - finalise, -- :: Weak v -> IO () + finalize, -- :: Weak v -> IO () -- Not yet implemented - -- replaceFinaliser -- :: Weak v -> IO () -> IO () + -- replaceFinalizer -- :: Weak v -> IO () -> IO () - mkWeakPtr, -- :: k -> IO () -> IO (Weak k) - mkWeakPair, -- :: k -> v -> IO () -> IO (Weak (k,v)) - mkWeakNoFinaliser, -- :: k -> v -> IO (Weak v) - addFinaliser, -- :: k -> IO () -> IO () - addForeignFinaliser -- :: ForeignObj -> IO () -> IO () + mkWeakPtr, -- :: k -> Maybe (IO ()) -> IO (Weak k) + mkWeakPair, -- :: k -> v -> Maybe (IO ()) -> IO (Weak (k,v)) + addFinalizer, -- :: k -> IO () -> IO () + addForeignFinalizer -- :: ForeignObj -> IO () -> IO () ) where @@ -61,8 +60,8 @@ occasionally, by deleting entries whose keys have died. The weak pointers in this library support another approach, called - mkWeakPtr :: a -> IO () -> IO (Weak a) + mkWeakPtr :: a -> Maybe (IO ()) -> IO (Weak a) deRefWeak :: Weak a -> IO (Maybe a) - addFinaliser :: a -> IO () -> IO () + addFinalizer :: a -> IO () -> IO () - - addFinaliser :: a -> IO () -> IO () - addFinaliser v f = do { mkWeakPtr v f; return () } + addFinalizer :: a -> IO () -> IO () + addFinalizer v f = do { mkWeakPtr v f; return () } -The effect of -Every finaliser will eventually be run, exactly once, either +Every finalizer will eventually be run, exactly once, either soon after the object dies, or at the end of the program. There is no requirement for the programmer to hold onto the weak pointer itself; finalisation is completely unaffected by whether the weak pointer itself is alive. There may be multiple weak pointers to a single object. -In this case, the finalisers for each of these weak pointers will +In this case, the finalizers for each of these weak pointers will all be run in some arbitrary order, or perhaps concurrently, -when the object dies. If the programmer specifies a finaliser that +when the object dies. If the programmer specifies a finalizer that assumes it has the only reference to an object (for example, a file that it wishes to close), then the programmer -must ensure that there is only one such finaliser. +must ensure that there is only one such finalizer. -The storage manager attempts to run the finaliser(s) for an +The storage manager attempts to run the finalizer(s) for an object soon after the object dies, but promptness is not guaranteed. -(What is guaranteed is that the finaliser will +(What is guaranteed is that the finalizer will eventually run, exactly once.) -At the moment when a finaliser is run, a call to -A finaliser may contain a pointer to the object, but that pointer +A finalizer may contain a pointer to the object, but that pointer will not keep the object alive. For example: f :: Show a => a -> IO a - f x = addFinaliser x (print (show x)) + f x = addFinalizer x (print (show x)) -Here the finaliser -A finaliser may even resurrect the object, by (say) storing it in +A finalizer may even resurrect the object, by (say) storing it in some global data structure. @@ -163,10 +161,10 @@ some global data structure. The - mkWeak :: k -> v -> IO () -> IO (Weak v) + mkWeak :: k -> v -> Maybe (IO ()) -> IO (Weak v) However, - mkWeakPtr :: a -> IO () -> IO (Weak a) + mkWeakPtr :: a -> Maybe (IO ()) -> IO (Weak a) mkWeakPtr v f = mkWeak v v f These more general weak pointers are enough to implement memo tables properly. -A weak pointer can be finalised early, using the -finalise :: Weak v -> IO () +finalize :: Weak v -> IO () -When you don't need a finaliser, we provide the following operation: - - -mkWeakNoFinaliser :: k -> v -> IO (Weak v) -mkWeakNoFinaliser k v = mkWeak k v (return ()) - - -Which creates a weak pointer with a null finaliser. Lots of null -finalisers can be expensive, because each one runs in a separate -thread, so the intention is that avoids all the -extra costs by generating a special kind of weak pointer without a -finaliser. So although the semantics of mkWeakNoFinaliser is as given -above, its actual implementation is somewhat different. - A precise semantics

The above informal specification is fine for simple situations, but matters can get complicated. In particular, it needs to be clear exactly when a key dies, so that any weak pointers -that refer to it can be finalised. +that refer to it can be finalized. Suppose, for example, the value of one weak pointer refers to the key of another...does that keep the key alive? @@ -222,9 +206,9 @@ The behaviour is simply this: If a weak pointer (object) refers to an Finalisation means (a) arrange that subsequent calls -to This behaviour depends on what it means for a key to be reachable. @@ -240,7 +224,7 @@ A heap object is reachable if: It is directly pointed to by a reachable object, other than a weak pointer object. It is a weak pointer object whose key is reachable. - It is the value or finaliser of an object whose key is + It is the value or finalizer of an object whose key is reachable. @@ -253,20 +237,20 @@ the garbage collector replaces heap-resident Finalisation for foreign objects -

A foreign object is some data that lives outside the Haskell heap, for example some ), and we must retain the invariant that @@ -275,9 +259,9 @@ retains the