]> Cypherpunks repositories - gostls13.git/commitdiff
sync: release m.mu during (*RWMutexMap).Range callbacks in sync_test
authorBryan C. Mills <bcmills@google.com>
Tue, 9 May 2017 20:12:57 +0000 (16:12 -0400)
committerBryan Mills <bcmills@google.com>
Thu, 20 Jul 2017 18:51:09 +0000 (18:51 +0000)
The mainline sync.Map has allowed mutations within Range callbacks
since https://golang.org/cl/37342. The reference implementations need
to do the same.

This change integrates https://go-review.googlesource.com/c/42956/
from x/sync.

Change-Id: I6b58cf874bb31cd4f6fdb8bfa8278888ed617a5a
Reviewed-on: https://go-review.googlesource.com/42957
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/sync/map_bench_test.go
src/sync/map_reference_test.go

index a5590a5ddc304a34854ca3267698166591a4bbd4..e6a8badddbafca3a9369dcded986b3a84ac5aa3c 100644 (file)
@@ -203,12 +203,10 @@ func BenchmarkAdversarialDelete(b *testing.B) {
                                m.Load(i)
 
                                if i%mapSize == 0 {
-                                       var key int
                                        m.Range(func(k, _ interface{}) bool {
-                                               key = k.(int)
+                                               m.Delete(k)
                                                return false
                                        })
-                                       m.Delete(key)
                                        m.Store(i, i)
                                }
                        }
index b21018c47f80f48a34791e0fa3b9acf75776bdfc..9f27b07c3292ba3dfa22e7039dc9882a1b80706c 100644 (file)
@@ -64,8 +64,17 @@ func (m *RWMutexMap) Delete(key interface{}) {
 
 func (m *RWMutexMap) Range(f func(key, value interface{}) (shouldContinue bool)) {
        m.mu.RLock()
-       defer m.mu.RUnlock()
-       for k, v := range m.dirty {
+       keys := make([]interface{}, 0, len(m.dirty))
+       for k := range m.dirty {
+               keys = append(keys, k)
+       }
+       m.mu.RUnlock()
+
+       for _, k := range keys {
+               v, ok := m.Load(k)
+               if !ok {
+                       continue
+               }
                if !f(k, v) {
                        break
                }