208302f8fcf2bb443b9612e940c8ce7bf65307df
[ghc-base.git] / System / Mem / Weak.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  System.Mem.Weak
4 -- Copyright   :  (c) The University of Glasgow 2001
5 -- License     :  BSD-style (see the file libraries/base/LICENSE)
6 -- 
7 -- Maintainer  :  libraries@haskell.org
8 -- Stability   :  experimental
9 -- Portability :  non-portable
10 --
11 -- In general terms, a weak pointer is a reference to an object that is
12 -- not followed by the garbage collector - that is, the existence of a
13 -- weak pointer to an object has no effect on the lifetime of that
14 -- object.  A weak pointer can be de-referenced to find out
15 -- whether the object it refers to is still alive or not, and if so
16 -- to return the object itself.
17 -- 
18 -- Weak pointers are particularly useful for caches and memo tables.
19 -- To build a memo table, you build a data structure 
20 -- mapping from the function argument (the key) to its result (the
21 -- value).  When you apply the function to a new argument you first
22 -- check whether the key\/value pair is already in the memo table.
23 -- The key point is that the memo table itself should not keep the
24 -- key and value alive.  So the table should contain a weak pointer
25 -- to the key, not an ordinary pointer.  The pointer to the value must
26 -- not be weak, because the only reference to the value might indeed be
27 -- from the memo table.   
28 -- 
29 -- So it looks as if the memo table will keep all its values
30 -- alive for ever.  One way to solve this is to purge the table
31 -- occasionally, by deleting entries whose keys have died.
32 -- 
33 -- The weak pointers in this library
34 -- support another approach, called /finalization/.
35 -- When the key referred to by a weak pointer dies, the storage manager
36 -- arranges to run a programmer-specified finalizer.  In the case of memo
37 -- tables, for example, the finalizer could remove the key\/value pair
38 -- from the memo table.  
39 -- 
40 -- Another difficulty with the memo table is that the value of a
41 -- key\/value pair might itself contain a pointer to the key.
42 -- So the memo table keeps the value alive, which keeps the key alive,
43 -- even though there may be no other references to the key so both should
44 -- die.  The weak pointers in this library provide a slight 
45 -- generalisation of the basic weak-pointer idea, in which each
46 -- weak pointer actually contains both a key and a value.
47 --
48 -----------------------------------------------------------------------------
49
50 module System.Mem.Weak (
51         -- * The @Weak@ type
52         Weak,                   -- abstract
53
54         -- * The general interface
55         mkWeak,                 -- :: k -> v -> Maybe (IO ()) -> IO (Weak v)
56         deRefWeak,              -- :: Weak v -> IO (Maybe v)
57         finalize,               -- :: Weak v -> IO ()
58
59         -- * Specialised versions
60         mkWeakPtr,              -- :: k -> Maybe (IO ()) -> IO (Weak k)
61         addFinalizer,           -- :: key -> IO () -> IO ()
62         mkWeakPair,             -- :: k -> v -> Maybe (IO ()) -> IO (Weak (k,v))
63         -- replaceFinaliser     -- :: Weak v -> IO () -> IO ()
64
65         -- * A precise semantics
66         
67         -- $precise
68    ) where
69
70 import Prelude
71
72 #ifdef __HUGS__
73 import Hugs.Weak
74 #endif
75
76 #ifdef __GLASGOW_HASKELL__
77 import GHC.Weak
78 #endif
79
80 -- | A specialised version of 'mkWeak', where the key and the value are
81 -- the same object:
82 --
83 -- > mkWeakPtr key finalizer = mkWeak key key finalizer
84 --
85 mkWeakPtr :: k -> Maybe (IO ()) -> IO (Weak k)
86 mkWeakPtr key finalizer = mkWeak key key finalizer
87
88 {-|
89   A specialised version of 'mkWeakPtr', where the 'Weak' object
90   returned is simply thrown away (however the finalizer will be
91   remembered by the garbage collector, and will still be run
92   when the key becomes unreachable).
93
94   Note: adding a finalizer to a 'Foreign.ForeignPtr.ForeignPtr' using
95   'addFinalizer' won't work as well as using the specialised version
96   'Foreign.ForeignPtr.addForeignPtrFinalizer' because the latter
97   version adds the finalizer to the primitive 'ForeignPtr#' object
98   inside, whereas the generic 'addFinalizer' will add the finalizer to
99   the box.  Optimisations tend to remove the box, which may cause the
100   finalizer to run earlier than you intended.  The same motivation
101   justifies the existence of
102   'Control.Concurrent.MVar.addMVarFinalizer' and
103   'Data.IORef.mkWeakIORef' (the non-uniformity is accidental).
104 -}
105 addFinalizer :: key -> IO () -> IO ()
106 addFinalizer key finalizer = do
107    _ <- mkWeakPtr key (Just finalizer) -- throw it away
108    return ()
109
110 -- | A specialised version of 'mkWeak' where the value is actually a pair
111 -- of the key and value passed to 'mkWeakPair':
112 --
113 -- > mkWeakPair key val finalizer = mkWeak key (key,val) finalizer
114 --
115 -- The advantage of this is that the key can be retrieved by 'deRefWeak'
116 -- in addition to the value.
117 mkWeakPair :: k -> v -> Maybe (IO ()) -> IO (Weak (k,v))
118 mkWeakPair key val finalizer = mkWeak key (key,val) finalizer
119
120
121 {- $precise
122
123 The above informal specification is fine for simple situations, but
124 matters can get complicated.  In particular, it needs to be clear
125 exactly when a key dies, so that any weak pointers that refer to it
126 can be finalized.  Suppose, for example, the value of one weak pointer
127 refers to the key of another...does that keep the key alive?
128
129 The behaviour is simply this:
130
131  *  If a weak pointer (object) refers to an /unreachable/
132     key, it may be finalized.
133
134  *  Finalization means (a) arrange that subsequent calls
135     to 'deRefWeak' return 'Nothing'; and (b) run the finalizer.
136
137 This behaviour depends on what it means for a key to be reachable.
138 Informally, something is reachable if it can be reached by following
139 ordinary pointers from the root set, but not following weak pointers.
140 We define reachability more precisely as follows A heap object is
141 reachable if:
142
143  * It is a member of the /root set/.
144
145  * It is directly pointed to by a reachable object, other than
146    a weak pointer object.
147
148  * It is a weak pointer object whose key is reachable.
149
150  * It is the value or finalizer of an object whose key is reachable.
151 -}