|
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