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