From 94953d3e5928c8a577bad7911aabbf627269ef77 Mon Sep 17 00:00:00 2001 From: Changkun Ou Date: Mon, 24 Aug 2020 13:45:27 +0200 Subject: sync: delete dirty keys inside Map.LoadAndDelete Fixes #40999 Change-Id: Ie32427e5cb5ed512b976b554850f50be156ce9f2 Reviewed-on: https://go-review.googlesource.com/c/go/+/250197 Run-TryBot: Emmanuel Odeke TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/sync/map_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/sync/map_test.go') diff --git a/src/sync/map_test.go b/src/sync/map_test.go index 4ae989a6d5..7f163caa5c 100644 --- a/src/sync/map_test.go +++ b/src/sync/map_test.go @@ -9,6 +9,7 @@ import ( "reflect" "runtime" "sync" + "sync/atomic" "testing" "testing/quick" ) @@ -171,3 +172,26 @@ func TestConcurrentRange(t *testing.T) { } } } + +func TestIssue40999(t *testing.T) { + var m sync.Map + + // Since the miss-counting in missLocked (via Delete) + // compares the miss count with len(m.dirty), + // add an initial entry to bias len(m.dirty) above the miss count. + m.Store(nil, struct{}{}) + + var finalized uint32 + + // Set finalizers that count for collected keys. A non-zero count + // indicates that keys have not been leaked. + for atomic.LoadUint32(&finalized) == 0 { + p := new(int) + runtime.SetFinalizer(p, func(*int) { + atomic.AddUint32(&finalized, 1) + }) + m.Store(p, struct{}{}) + m.Delete(p) + runtime.GC() + } +} -- cgit v1.3-5-g9baa