Remove Hugs98 specific code
[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 __GLASGOW_HASKELL__
74 import GHC.Weak
75 #endif
76
77 -- | A specialised version of 'mkWeak', where the key and the value are
78 -- the same object:
79 --
80 -- > mkWeakPtr key finalizer = mkWeak key key finalizer
81 --
82 mkWeakPtr :: k -> Maybe (IO ()) -> IO (Weak k)
83 mkWeakPtr key finalizer = mkWeak key key finalizer
84
85 {-|
86 A specialised version of 'mkWeakPtr', where the 'Weak' object
87 returned is simply thrown away (however the finalizer will be
88 remembered by the garbage collector, and will still be run
89 when the key becomes unreachable).
90
91 Note: adding a finalizer to a 'Foreign.ForeignPtr.ForeignPtr' using
92 'addFinalizer' won't work; use the specialised version
93 'Foreign.ForeignPtr.addForeignPtrFinalizer' instead. For discussion
94 see the 'Weak' type.
95 .
96 -}
97 addFinalizer :: key -> IO () -> IO ()
98 addFinalizer key finalizer = do
99 _ <- mkWeakPtr key (Just finalizer) -- throw it away
100 return ()
101
102 -- | A specialised version of 'mkWeak' where the value is actually a pair
103 -- of the key and value passed to 'mkWeakPair':
104 --
105 -- > mkWeakPair key val finalizer = mkWeak key (key,val) finalizer
106 --
107 -- The advantage of this is that the key can be retrieved by 'deRefWeak'
108 -- in addition to the value.
109 mkWeakPair :: k -> v -> Maybe (IO ()) -> IO (Weak (k,v))
110 mkWeakPair key val finalizer = mkWeak key (key,val) finalizer
111
112
113 {- $precise
114
115 The above informal specification is fine for simple situations, but
116 matters can get complicated. In particular, it needs to be clear
117 exactly when a key dies, so that any weak pointers that refer to it
118 can be finalized. Suppose, for example, the value of one weak pointer
119 refers to the key of another...does that keep the key alive?
120
121 The behaviour is simply this:
122
123 * If a weak pointer (object) refers to an /unreachable/
124 key, it may be finalized.
125
126 * Finalization means (a) arrange that subsequent calls
127 to 'deRefWeak' return 'Nothing'; and (b) run the finalizer.
128
129 This behaviour depends on what it means for a key to be reachable.
130 Informally, something is reachable if it can be reached by following
131 ordinary pointers from the root set, but not following weak pointers.
132 We define reachability more precisely as follows.
133
134 A heap object is /reachable/ if:
135
136 * It is a member of the /root set/.
137
138 * It is directly pointed to by a reachable object, other than
139 a weak pointer object.
140
141 * It is a weak pointer object whose key is reachable.
142
143 * It is the value or finalizer of a weak pointer object whose key is reachable.
144 -}
145