From 56d307f36beb66ed13c5f8d7325ee9e99cfb6c3b Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 11 Mar 2022 16:59:07 -0800 Subject: [PATCH] Fix a concurrency bug in `iterate(::Dict)` (#44534) (cherry picked from commit 6be86a380b09d0f02404140cb042f1ffb06c3442) --- NEWS.md | 9 +++++++-- base/dict.jl | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 916781b397dbeb..334517e2e95980 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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]). diff --git a/base/dict.jl b/base/dict.jl index cc5c9efb6ada85..901c9864e37e42 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -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))