Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | MLtonFinalizable |
2 | ================ | |
3 | ||
4 | [source,sml] | |
5 | ---- | |
6 | signature MLTON_FINALIZABLE = | |
7 | sig | |
8 | type 'a t | |
9 | ||
10 | val addFinalizer: 'a t * ('a -> unit) -> unit | |
11 | val finalizeBefore: 'a t * 'b t -> unit | |
12 | val new: 'a -> 'a t | |
13 | val touch: 'a t -> unit | |
14 | val withValue: 'a t * ('a -> 'b) -> 'b | |
15 | end | |
16 | ---- | |
17 | ||
18 | A _finalizable_ value is a container to which finalizers can be | |
19 | attached. A container holds a value, which is reachable as long as | |
20 | the container itself is reachable. A _finalizer_ is a function that | |
21 | runs at some point after garbage collection determines that the | |
22 | container to which it is attached has become | |
23 | <:Reachability:unreachable>. A finalizer is treated like a signal | |
24 | handler, in that it runs asynchronously in a separate thread, with | |
25 | signals blocked, and will not interrupt a critical section (see | |
26 | <:MLtonThread:>). | |
27 | ||
28 | * `addFinalizer (v, f)` | |
29 | + | |
30 | adds `f` as a finalizer to `v`. This means that sometime after the | |
31 | last call to `withValue` on `v` completes and `v` becomes unreachable, | |
32 | `f` will be called with the value of `v`. | |
33 | ||
34 | * `finalizeBefore (v1, v2)` | |
35 | + | |
36 | ensures that `v1` will be finalized before `v2`. A cycle of values | |
37 | `v` = `v1`, ..., `vn` = `v` with `finalizeBefore (vi, vi+1)` will | |
38 | result in none of the `vi` being finalized. | |
39 | ||
40 | * `new x` | |
41 | + | |
42 | creates a new finalizable value, `v`, with value `x`. The finalizers | |
43 | of `v` will run sometime after the last call to `withValue` on `v` | |
44 | when the garbage collector determines that `v` is unreachable. | |
45 | ||
46 | * `touch v` | |
47 | + | |
48 | ensures that `v`'s finalizers will not run before the call to `touch`. | |
49 | ||
50 | * `withValue (v, f)` | |
51 | + | |
52 | returns the result of applying `f` to the value of `v` and ensures | |
53 | that `v`'s finalizers will not run before `f` completes. The call to | |
54 | `f` is a nontail call. | |
55 | ||
56 | ||
57 | == Example == | |
58 | ||
59 | Suppose that `finalizable.sml` contains the following: | |
60 | [source,sml] | |
61 | ---- | |
62 | sys::[./bin/InclGitFile.py mlton master doc/examples/finalizable/finalizable.sml] | |
63 | ---- | |
64 | ||
65 | Suppose that `cons.c` contains the following. | |
66 | [source,c] | |
67 | ---- | |
68 | sys::[./bin/InclGitFile.py mlton master doc/examples/finalizable/cons.c] | |
69 | ---- | |
70 | ||
71 | We can compile these to create an executable with | |
72 | ---- | |
73 | % mlton -default-ann 'allowFFI true' finalizable.sml cons.c | |
74 | ---- | |
75 | ||
76 | Running this executable will create output like the following. | |
77 | ---- | |
78 | % finalizable | |
79 | 0x08072890 = listSing (2) | |
80 | 0x080728a0 = listCons (2) | |
81 | 0x080728b0 = listCons (2) | |
82 | 0x080728c0 = listCons (2) | |
83 | 0x080728d0 = listCons (2) | |
84 | 0x080728e0 = listCons (2) | |
85 | 0x080728f0 = listCons (2) | |
86 | listSum | |
87 | listSum(l) = 14 | |
88 | listFree (0x080728f0) | |
89 | listFree (0x080728e0) | |
90 | listFree (0x080728d0) | |
91 | listFree (0x080728c0) | |
92 | listFree (0x080728b0) | |
93 | listFree (0x080728a0) | |
94 | listFree (0x08072890) | |
95 | ---- | |
96 | ||
97 | ||
98 | == Synchronous Finalizers == | |
99 | ||
100 | Finalizers in MLton are asynchronous. That is, they run at an | |
101 | unspecified time, interrupting the user program. It is also possible, | |
102 | and sometimes useful, to have synchronous finalizers, where the user | |
103 | program explicitly decides when to run enabled finalizers. We have | |
104 | considered this in MLton, and it seems possible, but there are some | |
105 | unresolved design issues. See the thread at | |
106 | ||
107 | * http://www.mlton.org/pipermail/mlton/2004-September/016570.html | |
108 | ||
109 | == Also see == | |
110 | ||
111 | * <!Cite(Boehm03)> |