Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finalizers take function as first argument (closes #16307) #24605

Merged
merged 8 commits into from
Nov 21, 2017
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,13 @@ This section lists changes that do not have deprecation warnings.
* The return type of `reinterpret` has changed to `ReinterpretArray`. `reinterpret` on sparse
arrays has been discontinued.

* `Base.find_in_path` is now `Base.find_package` or `Base.find_source_file` ([#24320])
* `Base.find_in_path` is now `Base.find_package` or `Base.find_source_file` ([#24320]).

* `finalizer` now takes functions or pointers as its first argument, and the object being
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these lines have trailing whitespace, which is causing the CI failures. (It looks like we forgot to set up make check-whitespace on Circle CI.)

finalized as its second (rather than the reverse). For the majorities of uses cases this
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"For the majority of use cases, this change will..."

will trigger deprecation warnings. However, it will not if the 'function' is not a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"However, this change will not trigger deprecation warnings where: (1) the callable argument is not a subtype of Function; or (2) both arguments are Functions or Ptr{Void}s ..."

subtype of `Function`, nor will it for the ambiguous cases where both arguments are
`Function`s or `Ptr{Void}`s ([#24605]).

Library improvements
--------------------
Expand Down
11 changes: 11 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,17 @@ end
@deprecate chol!(x::Number, uplo) chol(x) false
end


# issue #16307
@deprecate finalizer(o, f::Function) finalizer(f, o)
# This misses other callables but they are very rare in the wild
@deprecate finalizer(o, f::Ptr{Void}) finalizer(f, o)

# Avoid ambiguity, can remove when deprecations are removed:
# This is almost certainly going to be a silent failure for code that is not updated.
finalizer(f::Ptr{Void}, o::Ptr{Void}) = invoke(finalizer, Tuple{Ptr{Void}, Any}, f, o)
finalizer(f::Ptr{Void}, o::Function) = invoke(finalizer, Tuple{Ptr{Void}, Any}, f, o)

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
6 changes: 5 additions & 1 deletion base/distributed/cluster.jl
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,11 @@ function create_worker(manager, wconfig)

w = Worker(w.id, r_s, w_s, manager; config=wconfig)
# install a finalizer to perform cleanup if necessary
finalizer(w, (w)->if myid() == 1 manage(w.manager, w.id, w.config, :finalize) end)
finalizer(w) do w
if myid() == 1
manage(w.manager, w.id, w.config, :finalize)
end
end

# set when the new worker has finshed connections with all other workers
ntfy_oid = RRID()
Expand Down
8 changes: 6 additions & 2 deletions base/distributed/clusterserialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ function serialize(s::ClusterSerializer, t::TypeName)
serialize_typename(s, t)
s.anonfunc_id = prev
push!(s.tn_obj_sent, identifier)
finalizer(t, x->cleanup_tname_glbs(s, identifier))
finalizer(t) do x
cleanup_tname_glbs(s, identifier)
end
end

# Send global refs if required.
Expand Down Expand Up @@ -133,7 +135,9 @@ function serialize_global_from_main(s::ClusterSerializer, sym)
elseif !haskey(s.glbs_sent, oid)
# set up a finalizer the first time this object is sent
try
finalizer(v, x->delete_global_tracker(s,x))
finalizer(v) do x
delete_global_tracker(s,x)
end
catch ex
# Do not track objects that cannot be finalized.
if isa(ex, ErrorException)
Expand Down
4 changes: 2 additions & 2 deletions base/distributed/remotecall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ function test_existing_ref(r::AbstractRemoteRef)
end

client_refs[r] = nothing
finalizer(r, finalize_ref)
finalizer(finalize_ref, r)
return r
end

function finalize_ref(r::AbstractRemoteRef)
if r.where > 0 # Handle the case of the finalizer having been called manually
islocked(client_refs) && return finalizer(r, finalize_ref) # delay finalizer for later, when it's not already locked
islocked(client_refs) && return finalizer(finalize_ref, r) # delay finalizer for later, when it's not already locked
delete!(client_refs, r)
if isa(r, RemoteChannel)
send_del_client(r)
Expand Down
2 changes: 1 addition & 1 deletion base/distributed/workerpool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ mutable struct CachingPool <: AbstractWorkerPool

function CachingPool()
wp = new(Channel{Int}(typemax(Int)), Set{Int}(), Dict{Int, Function}())
finalizer(wp, clear!)
finalizer(clear!, wp)
wp
end
end
Expand Down
4 changes: 2 additions & 2 deletions base/event.jl
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ mutable struct AsyncCondition
function AsyncCondition()
this = new(Libc.malloc(_sizeof_uv_async), Condition(), true)
associate_julia_struct(this.handle, this)
finalizer(this, uvfinalize)
finalizer(uvfinalize, this)
err = ccall(:uv_async_init, Cint, (Ptr{Void}, Ptr{Void}, Ptr{Void}),
eventloop(), this, uv_jl_asynccb::Ptr{Void})
if err != 0
Expand Down Expand Up @@ -372,7 +372,7 @@ mutable struct Timer
end

associate_julia_struct(this.handle, this)
finalizer(this, uvfinalize)
finalizer(uvfinalize, this)

ccall(:uv_update_time, Void, (Ptr{Void},), eventloop())
ccall(:uv_timer_start, Cint, (Ptr{Void}, Ptr{Void}, UInt64, UInt64),
Expand Down
6 changes: 3 additions & 3 deletions base/gcutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
==(w, v::WeakRef) = isequal(w, v.value)

"""
finalizer(x, f)
finalizer(f, x)

Register a function `f(x)` to be called when there are no program-accessible references to
`x`. The type of `x` must be a `mutable struct`, otherwise the behavior of this function is
unpredictable.
"""
function finalizer(@nospecialize(o), @nospecialize(f))
function finalizer(@nospecialize(f), @nospecialize(o))
if isimmutable(o)
error("objects of type ", typeof(o), " cannot be finalized")
end
ccall(:jl_gc_add_finalizer_th, Void, (Ptr{Void}, Any, Any),
Core.getptls(), o, f)
end

function finalizer(o::T, f::Ptr{Void}) where T
function finalizer(f::Ptr{Void}, o::T) where T
@_inline_meta
if isimmutable(T)
error("objects of type ", T, " cannot be finalized")
Expand Down
2 changes: 1 addition & 1 deletion base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ mutable struct BigInt <: Signed
function BigInt()
b = new(zero(Cint), zero(Cint), C_NULL)
MPZ.init!(b)
finalizer(b, cglobal((:__gmpz_clear, :libgmp)))
finalizer(cglobal((:__gmpz_clear, :libgmp)), b)
return b
end
end
Expand Down
2 changes: 1 addition & 1 deletion base/iostream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function IOStream(name::AbstractString, finalize::Bool)
buf = zeros(UInt8,sizeof_ios_t)
x = IOStream(name, buf)
if finalize
finalizer(x, close)
finalizer(close, x)
end
return x
end
Expand Down
2 changes: 1 addition & 1 deletion base/libgit2/gitcredential.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mutable struct GitCredential
username::Nullable{<:AbstractString},
password::Nullable{<:AbstractString})
c = new(protocol, host, path, username, password, true)
finalizer(c, securezero!)
finalizer(securezero!, c)
return c
end
end
Expand Down
10 changes: 5 additions & 5 deletions base/libgit2/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ for (typ, owntyp, sup, cname) in [
obj = new(ptr)
if fin
Threads.atomic_add!(REFCOUNT, UInt(1))
finalizer(obj, Base.close)
finalizer(Base.close, obj)
end
return obj
end
Expand All @@ -958,7 +958,7 @@ for (typ, owntyp, sup, cname) in [
obj = new(owner, ptr)
if fin
Threads.atomic_add!(REFCOUNT, UInt(1))
finalizer(obj, Base.close)
finalizer(Base.close, obj)
end
return obj
end
Expand Down Expand Up @@ -1000,7 +1000,7 @@ mutable struct GitSignature <: AbstractGitObject
function GitSignature(ptr::Ptr{SignatureStruct})
@assert ptr != C_NULL
obj = new(ptr)
finalizer(obj, Base.close)
finalizer(Base.close, obj)
return obj
end
end
Expand Down Expand Up @@ -1144,7 +1144,7 @@ mutable struct UserPasswordCredentials <: AbstractCredentials
pass::String
function UserPasswordCredentials(user::AbstractString="", pass::AbstractString="")
c = new(user, pass)
finalizer(c, securezero!)
finalizer(securezero!, c)
return c
end

Expand Down Expand Up @@ -1182,7 +1182,7 @@ mutable struct SSHCredentials <: AbstractCredentials
function SSHCredentials(user::AbstractString="", pass::AbstractString="",
prvkey::AbstractString="", pubkey::AbstractString="")
c = new(user, pass, prvkey, pubkey)
finalizer(c, securezero!)
finalizer(securezero!, c)
return c
end

Expand Down
2 changes: 1 addition & 1 deletion base/locks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ mutable struct Mutex <: AbstractLock
function Mutex()
m = new(zero(Int16), Libc.malloc(UV_MUTEX_SIZE))
ccall(:uv_mutex_init, Void, (Ptr{Void},), m.handle)
finalizer(m, _uv_hook_close)
finalizer(_uv_hook_close, m)
return m
end
end
Expand Down
4 changes: 2 additions & 2 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ mutable struct BigFloat <: AbstractFloat
prec = precision(BigFloat)
z = new(zero(Clong), zero(Cint), zero(Clong), C_NULL)
ccall((:mpfr_init2,:libmpfr), Void, (Ref{BigFloat}, Clong), z, prec)
finalizer(z, cglobal((:mpfr_clear, :libmpfr)))
finalizer(cglobal((:mpfr_clear, :libmpfr)), z)
return z
end

Expand Down Expand Up @@ -969,7 +969,7 @@ function Base.deepcopy_internal(x::BigFloat, stackdict::ObjectIdDict)
prec = precision(x)
y = BigFloat(zero(Clong), zero(Cint), zero(Clong), C_NULL)
ccall((:mpfr_init2,:libmpfr), Void, (Ref{BigFloat}, Clong), y, prec)
finalizer(y, cglobal((:mpfr_clear, :libmpfr)))
finalizer(cglobal((:mpfr_clear, :libmpfr)), y)
ccall((:mpfr_set, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), y, x, ROUNDING_MODE[])
stackdict[x] = y
return y
Expand Down
8 changes: 4 additions & 4 deletions base/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ precompile(Tuple{typeof(Base.copy!), Array{String, 1}, Int64, Array{Any, 1}, Int
precompile(Tuple{typeof(Base.empty!), Base.Dict{Int64, Union{Base.Distributed.Worker, Base.Distributed.LocalProcess}}})
precompile(Tuple{typeof(Core.Inference.isbits), Base.Distributed.DefaultClusterManager})
precompile(Tuple{typeof(Base.Distributed.init_worker), String, Base.Distributed.DefaultClusterManager})
precompile(Tuple{typeof(Base.finalizer), Base.TCPServer, typeof(Base.uvfinalize)})
precompile(Tuple{typeof(Base.finalizer), typeof(Base.uvfinalize), Base.TCPServer})
precompile(Tuple{Type{Base.TCPServer}, Ptr{Void}, Int64})
precompile(Tuple{typeof(Base.show), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Int32})
precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.Libc.RawFD})
Expand Down Expand Up @@ -105,7 +105,7 @@ precompile(Tuple{typeof(Core.Inference.start), Core.Inference.Generator{Tuple{Tu
precompile(Tuple{typeof(Core.Inference.done), Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{QuoteNode}}, Int64})
precompile(Tuple{typeof(Core.Inference.next), Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{QuoteNode}}, Int64})
precompile(Tuple{typeof(Core.Inference.isbits), Base.DevNullStream})
precompile(Tuple{typeof(Base.finalizer), Base.Process, typeof(Base.uvfinalize)})
precompile(Tuple{typeof(Base.finalizer), typeof(Base.uvfinalize), Base.Process})
precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Base.DevNullStream, Bool}})
precompile(Tuple{Type{Ref{Base.Cstring}}, Array{String, 1}})
precompile(Tuple{typeof(Core.Inference.eltype), Type{Array{String, 1}}})
Expand Down Expand Up @@ -1552,7 +1552,7 @@ precompile(Tuple{typeof(Base.rehash!), Base.Dict{WeakRef, Void}, Int64})
precompile(Tuple{typeof(Base.ht_keyindex2), Base.Dict{WeakRef, Void}, WeakRef})
precompile(Tuple{typeof(Base._setindex!), Base.Dict{WeakRef, Void}, Void, WeakRef, Int64})
precompile(Tuple{typeof(Base.setindex!), Base.Dict{WeakRef, Void}, Void, WeakRef})
precompile(Tuple{typeof(Base.finalizer), Base.Distributed.RemoteChannel{Base.Channel{Any}}, typeof(Base.Distributed.finalize_ref)})
precompile(Tuple{typeof(Base.finalizer), typeof(Base.Distributed.finalize_ref), Base.Distributed.RemoteChannel{Base.Channel{Any}}})
precompile(Tuple{typeof(Base.Distributed.test_existing_ref), Base.Distributed.RemoteChannel{Base.Channel{Any}}})
precompile(Tuple{Type{Base.Distributed.RemoteChannel{T} where T<:Base.AbstractChannel}, Int64})
precompile(Tuple{Type{Base.Channel{Int64}}, Int64})
Expand Down Expand Up @@ -1714,7 +1714,7 @@ precompile(Tuple{typeof(Base.Filesystem.mkdir), String, UInt16})
precompile(Tuple{typeof(Base.Filesystem.mkpath), String, UInt16})
precompile(Tuple{typeof(Base.Filesystem.samefile), String, String})
precompile(Tuple{typeof(Base.Filesystem.unlink), String})
precompile(Tuple{typeof(Base.finalizer), Base.Distributed.Future, typeof(Base.Distributed.finalize_ref)})
precompile(Tuple{typeof(Base.finalizer), typeof(Base.Distributed.finalize_ref), Base.Distributed.Future})
precompile(Tuple{typeof(Base.find_all_in_cache_path), Symbol})
precompile(Tuple{typeof(Base.find_package), String})
precompile(Tuple{typeof(Base.find_source_file), String})
Expand Down
2 changes: 1 addition & 1 deletion base/process.jl
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ mutable struct Process <: AbstractPipe
typemin(fieldtype(Process, :exitcode)),
typemin(fieldtype(Process, :termsignal)),
Condition(), Condition())
finalizer(this, uvfinalize)
finalizer(uvfinalize, this)
return this
end
end
Expand Down
8 changes: 4 additions & 4 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ mutable struct Regex
end
re = compile(new(pattern, compile_options, match_options, C_NULL,
C_NULL, Csize_t[], C_NULL))
finalizer(re, re->begin
re.regex == C_NULL || PCRE.free_re(re.regex)
re.match_data == C_NULL || PCRE.free_match_data(re.match_data)
end)
finalizer(re) do re
re.regex == C_NULL || PCRE.free_re(re.regex)
re.match_data == C_NULL || PCRE.free_match_data(re.match_data)
end
re
end
end
Expand Down
4 changes: 3 additions & 1 deletion base/repl/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,9 @@ function setup_interface(
try
hist_path = find_hist_file()
f = open(hist_path, true, true, true, false, false)
finalizer(replc, replc->close(f))
finalizer(replc) do replc
close(f)
end
hist_from_file(hp, f, hist_path)
catch e
print_response(repl, e, catch_backtrace(), true, Base.have_color)
Expand Down
6 changes: 3 additions & 3 deletions base/socket.jl
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ mutable struct TCPSocket <: LibuvStream
ReentrantLock(),
DEFAULT_READ_BUFFER_SZ)
associate_julia_struct(tcp.handle, tcp)
finalizer(tcp, uvfinalize)
finalizer(uvfinalize, tcp)
return tcp
end
end
Expand Down Expand Up @@ -308,7 +308,7 @@ mutable struct TCPServer <: LibuvServer
Condition(),
Condition())
associate_julia_struct(tcp.handle, tcp)
finalizer(tcp, uvfinalize)
finalizer(uvfinalize, tcp)
return tcp
end
end
Expand Down Expand Up @@ -370,7 +370,7 @@ mutable struct UDPSocket <: LibuvStream
Condition(),
Condition())
associate_julia_struct(udp.handle, udp)
finalizer(udp, uvfinalize)
finalizer(uvfinalize, udp)
return udp
end
end
Expand Down
6 changes: 3 additions & 3 deletions base/sparse/cholmod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ mutable struct Dense{T<:VTypes} <: DenseMatrix{T}
"unknown reasons. Please submit a bug report."))
end
A = new(p)
finalizer(A, free!)
finalizer(free!, A)
return A
end
end
Expand Down Expand Up @@ -256,7 +256,7 @@ mutable struct Sparse{Tv<:VTypes} <: AbstractSparseMatrix{Tv,SuiteSparse_long}
"unknown reasons. Please submit a bug report."))
end
A = new(p)
finalizer(A, free!)
finalizer(free!, A)
return A
end
end
Expand Down Expand Up @@ -340,7 +340,7 @@ mutable struct Factor{Tv} <: Factorization{Tv}
end
F = new(p)
if register_finalizer
finalizer(F, free!)
finalizer(free!, F)
end
return F
end
Expand Down
2 changes: 1 addition & 1 deletion base/sparse/umfpack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function lufact(S::SparseMatrixCSC{<:UMFVTypes,<:UMFITypes})
zerobased ? copy(S.colptr) : decrement(S.colptr),
zerobased ? copy(S.rowval) : decrement(S.rowval),
copy(S.nzval))
finalizer(res, umfpack_free_symbolic)
finalizer(umfpack_free_symbolic, res)
umfpack_numeric!(res)
end
lufact(A::SparseMatrixCSC{<:Union{Float16,Float32},Ti}) where {Ti<:UMFITypes} =
Expand Down
6 changes: 3 additions & 3 deletions base/stream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ mutable struct PipeEndpoint <: LibuvStream
ReentrantLock(),
DEFAULT_READ_BUFFER_SZ)
associate_julia_struct(handle, p)
finalizer(p, uvfinalize)
finalizer(uvfinalize, p)
return p
end
end
Expand All @@ -136,7 +136,7 @@ mutable struct PipeServer <: LibuvServer
Condition(),
Condition())
associate_julia_struct(p.handle, p)
finalizer(p, uvfinalize)
finalizer(uvfinalize, p)
return p
end
end
Expand Down Expand Up @@ -169,7 +169,7 @@ mutable struct TTY <: LibuvStream
nothing, ReentrantLock(),
DEFAULT_READ_BUFFER_SZ)
associate_julia_struct(handle, tty)
finalizer(tty, uvfinalize)
finalizer(uvfinalize, tty)
@static if Sys.iswindows()
tty.ispty = ccall(:jl_ispty, Cint, (Ptr{Void},), handle) != 0
end
Expand Down
Loading