aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/map.go
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2023-04-04 12:49:39 +0700
committerGopher Robot <gobot@golang.org>2023-04-08 05:25:04 +0000
commit231f290e51e130a1699d5c29d28133d68f43d2e9 (patch)
treef84b4c63e6565ec052fba14ea3bc115e76bde2d3 /src/runtime/map.go
parent66cac9e1e4877ac7e66f888b0599a7a4a5787b76 (diff)
downloadgo-231f290e51e130a1699d5c29d28133d68f43d2e9.tar.xz
runtime: mark map bucket slots as empty during map clear
So iterators that are in progress can know entries have been deleted and terminate the iterator properly. Update #55002 Update #56351 Fixes #59411 Change-Id: I924f16a00fe4ed6564f730a677348a6011d3fb67 Reviewed-on: https://go-review.googlesource.com/c/go/+/481935 Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/runtime/map.go')
-rw-r--r--src/runtime/map.go16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/runtime/map.go b/src/runtime/map.go
index 273e315ea0..9c3a7e2b8c 100644
--- a/src/runtime/map.go
+++ b/src/runtime/map.go
@@ -1008,6 +1008,22 @@ func mapclear(t *maptype, h *hmap) {
h.flags ^= hashWriting
+ // Mark buckets empty, so existing iterators can be terminated, see issue #59411.
+ markBucketsEmpty := func(bucket unsafe.Pointer, mask uintptr) {
+ for i := uintptr(0); i <= mask; i++ {
+ b := (*bmap)(add(bucket, i*uintptr(t.bucketsize)))
+ for ; b != nil; b = b.overflow(t) {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ b.tophash[i] = emptyRest
+ }
+ }
+ }
+ }
+ markBucketsEmpty(h.buckets, bucketMask(h.B))
+ if oldBuckets := h.oldbuckets; oldBuckets != nil {
+ markBucketsEmpty(oldBuckets, h.oldbucketmask())
+ }
+
h.flags &^= sameSizeGrow
h.oldbuckets = nil
h.nevacuate = 0