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