Skip to content

Commit

Permalink
Fix a concurrency bug in iterate(::Dict) (#44534)
Browse files Browse the repository at this point in the history
(cherry picked from commit 6be86a3)
  • Loading branch information
tkf authored and KristofferC committed May 23, 2022
1 parent b7e4497 commit 06d71b8
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
9 changes: 7 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,13 @@ New library functions
* New function `Base.rest` for taking the rest of a collection, starting from a specific
iteration state, in a generic way ([#37410]).

New library features
--------------------
Library changes
---------------

* A known concurrency issue of `iterate` methods on `Dict` and other derived objects such
as `keys(::Dict)`, `values(::Dict)`, and `Set` is fixed. These methods of `iterate` can
now be called on a dictionary or set shared by arbitrary tasks provided that there are no
tasks mutating the dictionary or set ([#44534]).

* The `redirect_*` functions now accept `devnull` to discard all output redirected to it, and as an empty
input ([#36146]).
Expand Down
2 changes: 1 addition & 1 deletion base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ end

@propagate_inbounds _iterate(t::Dict{K,V}, i) where {K,V} = i == 0 ? nothing : (Pair{K,V}(t.keys[i],t.vals[i]), i == typemax(Int) ? 0 : i+1)
@propagate_inbounds function iterate(t::Dict)
_iterate(t, skip_deleted_floor!(t))
_iterate(t, skip_deleted(t, t.idxfloor))
end
@propagate_inbounds iterate(t::Dict, i) = _iterate(t, skip_deleted(t, i))

Expand Down

0 comments on commit 06d71b8

Please sign in to comment.