From b0bf9c208db9f4708ea141fd09d0cc0231ac8358 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 14 Nov 2017 23:00:33 +0800 Subject: [PATCH 1/8] =make finalizers take function as first argument --- base/deprecated.jl | 14 ++++++++++++++ base/gcutils.jl | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 78eabaafc219e..674b51ea9151d 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -2097,6 +2097,20 @@ 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::T, f::Ptr{Void}) where {T} 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 diff --git a/base/gcutils.jl b/base/gcutils.jl index e42cc9e6de303..b40108b08685a 100644 --- a/base/gcutils.jl +++ b/base/gcutils.jl @@ -5,13 +5,13 @@ ==(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 @@ -19,7 +19,7 @@ function finalizer(@nospecialize(o), @nospecialize(f)) 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") From 747444bde3e689ad5a3deb9127e6bbee3e02c5b1 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 14 Nov 2017 23:00:58 +0800 Subject: [PATCH 2/8] =update all files so finalizers take functions as their first argument --- base/distributed/cluster.jl | 6 +++++- base/distributed/clusterserialize.jl | 8 ++++++-- base/distributed/remotecall.jl | 4 ++-- base/distributed/workerpool.jl | 2 +- base/event.jl | 4 ++-- base/gmp.jl | 2 +- base/iostream.jl | 2 +- base/libgit2/gitcredential.jl | 2 +- base/libgit2/types.jl | 10 +++++----- base/locks.jl | 2 +- base/mpfr.jl | 4 ++-- base/precompile.jl | 8 ++++---- base/process.jl | 2 +- base/regex.jl | 8 ++++---- base/repl/REPL.jl | 4 +++- base/socket.jl | 6 +++--- base/sparse/cholmod.jl | 6 +++--- base/sparse/umfpack.jl | 2 +- base/stream.jl | 6 +++--- base/weakkeydict.jl | 8 ++++---- stdlib/Base64/src/encode.jl | 2 +- stdlib/FileWatching/src/FileWatching.jl | 12 ++++++------ stdlib/FileWatching/test/runtests.jl | 2 +- stdlib/Mmap/src/Mmap.jl | 4 ++-- stdlib/SharedArrays/src/SharedArrays.jl | 2 +- test/ccall.jl | 4 ++-- test/channels.jl | 2 +- test/codegen.jl | 2 +- test/core.jl | 20 ++++++++++---------- test/dict.jl | 6 +++--- test/misc.jl | 2 +- 31 files changed, 82 insertions(+), 72 deletions(-) diff --git a/base/distributed/cluster.jl b/base/distributed/cluster.jl index 34d367ecdbaa5..e05ca8e7f84e2 100644 --- a/base/distributed/cluster.jl +++ b/base/distributed/cluster.jl @@ -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() diff --git a/base/distributed/clusterserialize.jl b/base/distributed/clusterserialize.jl index 2a42f35a7f572..4a61f59710a2e 100644 --- a/base/distributed/clusterserialize.jl +++ b/base/distributed/clusterserialize.jl @@ -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. @@ -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) diff --git a/base/distributed/remotecall.jl b/base/distributed/remotecall.jl index 1e87ba22b6698..b3503c4cc5339 100644 --- a/base/distributed/remotecall.jl +++ b/base/distributed/remotecall.jl @@ -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) diff --git a/base/distributed/workerpool.jl b/base/distributed/workerpool.jl index 7aedd63c844c4..cd034a7effd90 100644 --- a/base/distributed/workerpool.jl +++ b/base/distributed/workerpool.jl @@ -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 diff --git a/base/event.jl b/base/event.jl index f3b67726fea2e..5179e096714d4 100644 --- a/base/event.jl +++ b/base/event.jl @@ -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 @@ -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), diff --git a/base/gmp.jl b/base/gmp.jl index 33eaa6e704c9a..5cb20f3189e77 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -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 diff --git a/base/iostream.jl b/base/iostream.jl index 33452f487fba3..24513f25e0f3d 100644 --- a/base/iostream.jl +++ b/base/iostream.jl @@ -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 diff --git a/base/libgit2/gitcredential.jl b/base/libgit2/gitcredential.jl index 5c38941341f8d..0ef25d4130f94 100644 --- a/base/libgit2/gitcredential.jl +++ b/base/libgit2/gitcredential.jl @@ -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 diff --git a/base/libgit2/types.jl b/base/libgit2/types.jl index 20a2efc643239..7c4e21b9a77d0 100644 --- a/base/libgit2/types.jl +++ b/base/libgit2/types.jl @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/base/locks.jl b/base/locks.jl index e674d5d877191..6bf9c1274bc74 100644 --- a/base/locks.jl +++ b/base/locks.jl @@ -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 diff --git a/base/mpfr.jl b/base/mpfr.jl index 743a814e1af88..3048657ee59d3 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -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 @@ -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 diff --git a/base/precompile.jl b/base/precompile.jl index 2ccd832138828..37ded112a894a 100644 --- a/base/precompile.jl +++ b/base/precompile.jl @@ -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}) @@ -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}}}) @@ -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}) @@ -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}) diff --git a/base/process.jl b/base/process.jl index 8ad5063bab30b..9ce979b4c441f 100644 --- a/base/process.jl +++ b/base/process.jl @@ -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 diff --git a/base/regex.jl b/base/regex.jl index b82b7b75e3a05..344730007d7ec 100644 --- a/base/regex.jl +++ b/base/regex.jl @@ -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 diff --git a/base/repl/REPL.jl b/base/repl/REPL.jl index 72203878b1696..d741824fec5d2 100644 --- a/base/repl/REPL.jl +++ b/base/repl/REPL.jl @@ -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) diff --git a/base/socket.jl b/base/socket.jl index 15330cd493556..541e1189bf844 100644 --- a/base/socket.jl +++ b/base/socket.jl @@ -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 @@ -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 @@ -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 diff --git a/base/sparse/cholmod.jl b/base/sparse/cholmod.jl index e68417cad7a36..ac73c631d096c 100644 --- a/base/sparse/cholmod.jl +++ b/base/sparse/cholmod.jl @@ -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 @@ -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 @@ -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 diff --git a/base/sparse/umfpack.jl b/base/sparse/umfpack.jl index c71b6d2b65961..8355312cbbb66 100644 --- a/base/sparse/umfpack.jl +++ b/base/sparse/umfpack.jl @@ -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} = diff --git a/base/stream.jl b/base/stream.jl index 15d050dc0ee60..4cf2d753f67ef 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -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 @@ -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 @@ -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 diff --git a/base/weakkeydict.jl b/base/weakkeydict.jl index 1ff64f5b172b1..c4307271d7179 100644 --- a/base/weakkeydict.jl +++ b/base/weakkeydict.jl @@ -21,7 +21,7 @@ mutable struct WeakKeyDict{K,V} <: Associative{K,V} t = new(Dict{Any,V}(), Threads.RecursiveSpinLock(), identity) t.finalizer = function (k) # when a weak key is finalized, remove from dictionary if it is still there - islocked(t) && return finalizer(k, t.finalizer) + islocked(t) && return finalizer(t.finalizer, k) delete!(t, k) end return t @@ -89,7 +89,7 @@ trylock(f, wkh::WeakKeyDict) = trylock(f, wkh.lock) function setindex!(wkh::WeakKeyDict{K}, v, key) where K k = convert(K, key) - finalizer(k, wkh.finalizer) + finalizer(wkh.finalizer, k) lock(wkh) do wkh.ht[WeakRef(k)] = v end @@ -119,12 +119,12 @@ length(t::WeakKeyDict) = length(t.ht) function start(t::WeakKeyDict{K,V}) where V where K gc_token = Ref{Bool}(false) # no keys will be deleted via finalizers until this token is gc'd - finalizer(gc_token, function(r) + finalizer(gc_token) do r if r[] r[] = false unlock(t.lock) end - end) + end s = lock(t.lock) gc_token[] = true return (start(t.ht), gc_token) diff --git a/stdlib/Base64/src/encode.jl b/stdlib/Base64/src/encode.jl index 37dda446cd525..be44d5da07b92 100644 --- a/stdlib/Base64/src/encode.jl +++ b/stdlib/Base64/src/encode.jl @@ -39,7 +39,7 @@ struct Base64EncodePipe <: IO # The buffer size must be at least 3. buffer = Buffer(512) pipe = new(io, buffer) - finalizer(buffer, _ -> close(pipe)) + finalizer(_ -> close(pipe), buffer) return pipe end end diff --git a/stdlib/FileWatching/src/FileWatching.jl b/stdlib/FileWatching/src/FileWatching.jl index 5d2735dac8244..a8f91228f138b 100644 --- a/stdlib/FileWatching/src/FileWatching.jl +++ b/stdlib/FileWatching/src/FileWatching.jl @@ -75,7 +75,7 @@ mutable struct FileMonitor Libc.free(handle) throw(UVError("FileMonitor", err)) end - finalizer(this, uvfinalize) + finalizer(uvfinalize, this) return this end end @@ -96,7 +96,7 @@ mutable struct PollingFileWatcher Libc.free(handle) throw(UVError("PollingFileWatcher", err)) end - finalizer(this, uvfinalize) + finalizer(uvfinalize, this) return this end end @@ -144,7 +144,7 @@ mutable struct _FDWatcher Libc.free(handle) throw(UVError("FDWatcher", err)) end - finalizer(this, uvfinalize) + finalizer(uvfinalize, this) FDWatchers[fdnum] = this return this end @@ -189,7 +189,7 @@ mutable struct _FDWatcher associate_julia_struct(handle, this) err = ccall(:uv_poll_init_socket, Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}), eventloop(), handle, fd.handle) - finalizer(this, uvfinalize) + finalizer(uvfinalize, this) if err != 0 Libc.free(handle) throw(UVError("FDWatcher", err)) @@ -206,13 +206,13 @@ mutable struct FDWatcher # WARNING: make sure `close` has been manually called on this watcher before closing / destroying `fd` function FDWatcher(fd::RawFD, readable::Bool, writable::Bool) this = new(_FDWatcher(fd, readable, writable), readable, writable) - finalizer(this, close) + finalizer(close, this) return this end @static if Sys.iswindows() function FDWatcher(fd::WindowsRawSocket, readable::Bool, writable::Bool) this = new(_FDWatcher(fd, readable, writable), readable, writable) - finalizer(this, close) + finalizer(close, this) return this end end diff --git a/stdlib/FileWatching/test/runtests.jl b/stdlib/FileWatching/test/runtests.jl index d6b0c3aeb7e0d..a39a8c9c74517 100644 --- a/stdlib/FileWatching/test/runtests.jl +++ b/stdlib/FileWatching/test/runtests.jl @@ -133,7 +133,7 @@ end # make sure repeating timers work @noinline function make_unrooted_timer(a) t = Timer(0.0, 0.1) - finalizer(t, t -> a[] += 1) + finalizer(t -> a[] += 1, t) wait(t) e = @elapsed for i = 1:5 wait(t) diff --git a/stdlib/Mmap/src/Mmap.jl b/stdlib/Mmap/src/Mmap.jl index 93c06ced89d1b..93eff5569c325 100644 --- a/stdlib/Mmap/src/Mmap.jl +++ b/stdlib/Mmap/src/Mmap.jl @@ -206,7 +206,7 @@ function mmap(io::IO, end # os-test # convert mmapped region to Julia Array at `ptr + (offset - offset_page)` since file was mapped at offset_page A = unsafe_wrap(Array, convert(Ptr{T}, UInt(ptr) + UInt(offset - offset_page)), dims) - finalizer(A, function(x) + finalizer(A) do x @static if Sys.isunix() systemerror("munmap", ccall(:munmap, Cint, (Ptr{Void}, Int), ptr, mmaplen) != 0) else @@ -214,7 +214,7 @@ function mmap(io::IO, status |= ccall(:CloseHandle, stdcall, Cint, (Ptr{Void},), handle)!=0 status || error("could not unmap view: $(Libc.FormatMessage())") end - end) + end return A end diff --git a/stdlib/SharedArrays/src/SharedArrays.jl b/stdlib/SharedArrays/src/SharedArrays.jl index 585a10a8049de..c5ac5ce01ae60 100644 --- a/stdlib/SharedArrays/src/SharedArrays.jl +++ b/stdlib/SharedArrays/src/SharedArrays.jl @@ -255,7 +255,7 @@ function initialize_shared_array(S, onlocalhost, init, pids) end end - finalizer(S, finalize_refs) + finalizer(finalize_refs, S) S end diff --git a/test/ccall.jl b/test/ccall.jl index 2f26ba5fae1e1..1b243b1dba6fd 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -881,13 +881,13 @@ end let A = [1] ccall((:set_c_int, libccalltest), Void, (Cint,), 1) @test ccall((:get_c_int, libccalltest), Cint, ()) == 1 - finalizer(A, cglobal((:finalizer_cptr, libccalltest), Void)) + finalizer(cglobal((:finalizer_cptr, libccalltest), Void), A) finalize(A) @test ccall((:get_c_int, libccalltest), Cint, ()) == -1 end # Pointer finalizer at exit (PR #19911) -let result = read(`$(Base.julia_cmd()) --startup-file=no -e "A = Ref{Cint}(42); finalizer(A, cglobal((:c_exit_finalizer, \"$libccalltest\"), Void))"`, String) +let result = read(`$(Base.julia_cmd()) --startup-file=no -e "A = Ref{Cint}(42); finalizer(cglobal((:c_exit_finalizer, \"$libccalltest\"), Void), A)"`, String) @test result == "c_exit_finalizer: 42, 0" end diff --git a/test/channels.jl b/test/channels.jl index d06592bb47e03..8a65ced7cd40a 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -226,7 +226,7 @@ end # test for yield/wait/event failures -@noinline garbage_finalizer(f) = finalizer("gar" * "bage", f) +@noinline garbage_finalizer(f) = finalizer(f, "gar" * "bage") let t, run = Ref(0) gc_enable(false) # test for finalizers trying to yield leading to failed attempts to context switch diff --git a/test/codegen.jl b/test/codegen.jl index c24e35b5ecff1..7683be2ff8a51 100644 --- a/test/codegen.jl +++ b/test/codegen.jl @@ -221,7 +221,7 @@ let was_gced = false function foo22770() b = Ref(2) - finalizer(b, x -> was_gced = true) + finalizer(x -> was_gced = true, b) y = make_tuple(b) x = y[1] a = Ref(1) diff --git a/test/core.jl b/test/core.jl index 6a84a56d9e0b2..40df874bb44e9 100644 --- a/test/core.jl +++ b/test/core.jl @@ -896,7 +896,7 @@ end # finalizers let A = [1] local x = 0 - finalizer(A, a->(x+=1)) + finalizer(a->(x+=1), A) finalize(A) @test x == 1 A = 0 @@ -3593,7 +3593,7 @@ end let obj = Ref(1) finalized = 0 - finalizer(obj, (obj) -> (finalized = 1)) + finalizer((obj) -> (finalized = 1), obj) # obj should be marked for promotion after the second gc and be promoted # after the third GC # GC_CLEAN; age = 0 @@ -3623,10 +3623,10 @@ let obj1 = Ref(1) obj2 = Ref(1) finalized = 0 - finalizer(obj1, (obj) -> (finalized += 1)) - finalizer(obj1, (obj) -> (finalized += 1)) - finalizer(obj2, (obj) -> (finalized += 1; finalize(obj1))) - finalizer(obj2, (obj) -> (finalized += 1; finalize(obj1))) + finalizer((obj) -> (finalized += 1), obj1) + finalizer((obj) -> (finalized += 1), obj1) + finalizer((obj) -> (finalized += 1; finalize(obj1)), obj2) + finalizer((obj) -> (finalized += 1; finalize(obj1)), obj2) finalize(obj2) @test finalized == 4 end @@ -3963,10 +3963,10 @@ end # doesn't keep the object alive. @noinline function create_dead_object13995(finalized) obj = Ref(1) - finalizer(obj, (x)->(finalized[1] = true)) - finalizer(obj, (x)->(finalized[2] = true)) - finalizer(obj, (x)->(finalized[3] = true)) - finalizer(obj, (x)->(finalized[4] = true)) + finalizer((x)->(finalized[1] = true), obj) + finalizer((x)->(finalized[2] = true), obj) + finalizer((x)->(finalized[3] = true), obj) + finalizer((x)->(finalized[4] = true), obj) nothing end # disable GC to make sure no collection/promotion happens diff --git a/test/dict.jl b/test/dict.jl index 8c0f22e383592..77df74d3e0625 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -613,9 +613,9 @@ Dict(1 => rand(2,3), 'c' => "asdf") # just make sure this does not trigger a dep local x = 0 local y = 0 local z = 0 - finalizer(A, a->(x+=1)) - finalizer(B, b->(y+=1)) - finalizer(C, c->(z+=1)) + finalizer(a->(x+=1), A) + finalizer(b->(y+=1), B) + finalizer(c->(z+=1), C) # construction wkd = WeakKeyDict() diff --git a/test/misc.jl b/test/misc.jl index 75d5a2012c971..33f4dcca2c671 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -269,7 +269,7 @@ end @noinline function f6597(c) t = @schedule nothing - finalizer(t, t -> c[] += 1) + finalizer(t -> c[] += 1, t) wait(t) @test c[] == 0 wait(t) From 1534c38a07a3eea8695393ddaa92f49be182729e Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Wed, 15 Nov 2017 08:17:44 +0800 Subject: [PATCH 3/8] =remove pointless type constraint --- base/deprecated.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 674b51ea9151d..7ceafb95e36e7 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -2101,16 +2101,13 @@ 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::T, f::Ptr{Void}) where {T} finalizer(f, o) - +@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 From 687e86abc21eacc0058db3b4b5ad5fb04c16f4ae Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Wed, 15 Nov 2017 16:52:09 +0800 Subject: [PATCH 4/8] =add news for #24605 --- NEWS.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 1ac663ea1be88..7466bc0b2c407 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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 + finalized as its second (rather than the reverse). For the majorities of uses cases this + will trigger deprecation warnings. However, it will not if the 'function' is not a + subtype of `Function`, nor will it for the ambiguous cases where both arguments are + `Function`s or `Ptr{Void}`s ([#24605]). Library improvements -------------------- From 1c3b17af77c1ff9e5e4a7c5e030853934f0c230e Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Thu, 16 Nov 2017 09:49:45 +0800 Subject: [PATCH 5/8] =spaces not tabs --- NEWS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 7466bc0b2c407..c1c86d19d1ade 100644 --- a/NEWS.md +++ b/NEWS.md @@ -271,9 +271,9 @@ This section lists changes that do not have deprecation warnings. * `finalizer` now takes functions or pointers as its first argument, and the object being finalized as its second (rather than the reverse). For the majorities of uses cases this - will trigger deprecation warnings. However, it will not if the 'function' is not a - subtype of `Function`, nor will it for the ambiguous cases where both arguments are - `Function`s or `Ptr{Void}`s ([#24605]). + will trigger deprecation warnings. However, it will not if the 'function' is not a + subtype of `Function`, nor will it for the ambiguous cases where both arguments are + `Function`s or `Ptr{Void}`s ([#24605]). Library improvements -------------------- From 03ff4fbd2ad07dcdb2fae49e2fd27fc13928e50e Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 21 Nov 2017 10:39:26 +0800 Subject: [PATCH 6/8] =fix whitespacing and phrasing --- NEWS.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index c1c86d19d1ade..ded3eb9774883 100644 --- a/NEWS.md +++ b/NEWS.md @@ -269,10 +269,10 @@ This section lists changes that do not have deprecation warnings. * `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 - finalized as its second (rather than the reverse). For the majorities of uses cases this - will trigger deprecation warnings. However, it will not if the 'function' is not a - subtype of `Function`, nor will it for the ambiguous cases where both arguments are + * `finalizer` now takes functions or pointers as its first argument, and the object being + finalized as its second (rather than the reverse). For the majorities of use cases + deprecation warnings will be triggered. However, deprecation warning will not trigger where: + (1) the callable argument is not a subtype of `Function`; or (2) when both arguments are `Function`s or `Ptr{Void}`s ([#24605]). Library improvements From f94d5c97b371c61cab79736767eede23468d85b9 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 21 Nov 2017 11:04:02 +0800 Subject: [PATCH 7/8] =writing news --- NEWS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index ded3eb9774883..7096b41d18caf 100644 --- a/NEWS.md +++ b/NEWS.md @@ -271,8 +271,8 @@ This section lists changes that do not have deprecation warnings. * `finalizer` now takes functions or pointers as its first argument, and the object being finalized as its second (rather than the reverse). For the majorities of use cases - deprecation warnings will be triggered. However, deprecation warning will not trigger where: - (1) the callable argument is not a subtype of `Function`; or (2) when both arguments are + deprecation warnings will be triggered. However, deprecation warnings will not trigger where + (1) the callable argument is not a subtype of `Function`; or (2) both arguments are `Function`s or `Ptr{Void}`s ([#24605]). Library improvements From 9516d83251ced9a368177e76b6d5f6b8d359c6e1 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 21 Nov 2017 11:04:47 +0800 Subject: [PATCH 8/8] =writing news --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 7096b41d18caf..71fbb3bf5b562 100644 --- a/NEWS.md +++ b/NEWS.md @@ -270,7 +270,7 @@ This section lists changes that do not have deprecation warnings. * `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 - finalized as its second (rather than the reverse). For the majorities of use cases + finalized as its second (rather than the reverse). For the majority of use cases deprecation warnings will be triggered. However, deprecation warnings will not trigger where (1) the callable argument is not a subtype of `Function`; or (2) both arguments are `Function`s or `Ptr{Void}`s ([#24605]).