Skip to content

Commit

Permalink
remove gc-token from WeakKeyDict (#33825)
Browse files Browse the repository at this point in the history
This was a hold-over from the old iteration protocol, which needed to maintain state between `done` and `next`.
The `iteration` function of `Dict` has since been re-written to be safe for concurrent deletions.

Replaces: #33756
Co-Authored-By: Hans-Peter Suter <hps@treetron.ch>
(cherry picked from commit 1731d0a)
  • Loading branch information
vtjnash authored and KristofferC committed Feb 22, 2020
1 parent ea009f6 commit 0c4a248
Showing 1 changed file with 5 additions and 17 deletions.
22 changes: 5 additions & 17 deletions base/weakkeydict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
WeakKeyDict([itr])
`WeakKeyDict()` constructs a hash table where the keys are weak
references to objects, and thus may be garbage collected even when
references to objects which may be garbage collected even when
referenced in a hash table.
See [`Dict`](@ref) for further help. Note, unlike [`Dict`](@ref),
Expand Down Expand Up @@ -111,24 +111,12 @@ getindex(wkh::WeakKeyDict{K}, key) where {K} = lock(() -> getindex(wkh.ht, key),
isempty(wkh::WeakKeyDict) = isempty(wkh.ht)
length(t::WeakKeyDict) = length(t.ht)

function iterate(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) do r
if r[]
r[] = false
unlock(t.lock)
end
end
s = lock(t.lock)
iterate(t, (gc_token,))
end
function iterate(t::WeakKeyDict{K,V}, state) where V where K
gc_token = first(state)
y = iterate(t.ht, tail(state)...)
function iterate(t::WeakKeyDict{K,V}, state...) where {K, V}
y = lock(() -> iterate(t.ht, state...), t)
y === nothing && return nothing
wkv, i = y
wkv, newstate = y
kv = Pair{K,V}(wkv[1].value::K, wkv[2])
return (kv, (gc_token, i))
return (kv, newstate)
end

filter!(f, d::WeakKeyDict) = filter_in_one_pass!(f, d)

0 comments on commit 0c4a248

Please sign in to comment.