|
4 | 4 | ==(w::WeakRef, v) = isequal(w.value, v) |
5 | 5 | ==(w, v::WeakRef) = isequal(w, v.value) |
6 | 6 |
|
| 7 | +# Used by `Base.finalizer` to validate mutability of an object being finalized. |
| 8 | +function _check_mutable(@nospecialize(o)) @noinline |
| 9 | + if !ismutable(o) |
| 10 | + error("objects of type ", typeof(o), " cannot be finalized") |
| 11 | + end |
| 12 | +end |
| 13 | + |
7 | 14 | """ |
8 | 15 | finalizer(f, x) |
9 | 16 |
|
10 | 17 | Register a function `f(x)` to be called when there are no program-accessible references to |
11 | | -`x`, and return `x`. The type of `x` must be a `mutable struct`, otherwise the behavior of |
12 | | -this function is unpredictable. |
| 18 | +`x`, and return `x`. The type of `x` must be a `mutable struct`, otherwise the function |
| 19 | +will throw. |
13 | 20 |
|
14 | 21 | `f` must not cause a task switch, which excludes most I/O operations such as `println`. |
15 | 22 | Using the `@async` macro (to defer context switching to outside of the finalizer) or |
16 | 23 | `ccall` to directly invoke IO functions in C may be helpful for debugging purposes. |
17 | 24 |
|
| 25 | +Note that there is no guaranteed world age for the execution of `f`. It may be |
| 26 | +called in the world age in which the finalizer was registered or any later world age. |
| 27 | +
|
18 | 28 | # Examples |
19 | 29 | ```julia |
20 | 30 | finalizer(my_mutable_struct) do x |
|
42 | 52 | ``` |
43 | 53 | """ |
44 | 54 | function finalizer(@nospecialize(f), @nospecialize(o)) |
45 | | - if !ismutable(o) |
46 | | - error("objects of type ", typeof(o), " cannot be finalized") |
47 | | - end |
48 | | - ccall(:jl_gc_add_finalizer_th, Cvoid, (Ptr{Cvoid}, Any, Any), |
49 | | - Core.getptls(), o, f) |
| 55 | + _check_mutable(o) |
| 56 | + Core.finalizer(f, o) |
50 | 57 | return o |
51 | 58 | end |
52 | 59 |
|
53 | 60 | function finalizer(f::Ptr{Cvoid}, o::T) where T @inline |
54 | | - if !ismutable(o) |
55 | | - error("objects of type ", typeof(o), " cannot be finalized") |
56 | | - end |
| 61 | + _check_mutable(o) |
57 | 62 | ccall(:jl_gc_add_ptr_finalizer, Cvoid, (Ptr{Cvoid}, Any, Ptr{Cvoid}), |
58 | 63 | Core.getptls(), o, f) |
59 | 64 | return o |
|
0 commit comments