File tree Expand file tree Collapse file tree 2 files changed +47
-3
lines changed Expand file tree Collapse file tree 2 files changed +47
-3
lines changed Original file line number Diff line number Diff line change @@ -66,31 +66,46 @@ func (s *safeStats) Get() stats.Stats {
6666}
6767
6868func (s * safeStats ) Index () statsItemAddr {
69+ s .mu .RLock ()
70+ defer s .mu .RUnlock ()
71+
6972 return statsItemAddr {
7073 v : & s .v .Index ,
7174 onChange : func (f func ()) {
7275 s .mu .WithLock (f )
73- s .onChange (s .v )
76+ if s .onChange != nil {
77+ s .onChange (s .Get ())
78+ }
7479 },
7580 }
7681}
7782
7883func (s * safeStats ) Idle () statsItemAddr {
84+ s .mu .RLock ()
85+ defer s .mu .RUnlock ()
86+
7987 return statsItemAddr {
8088 v : & s .v .Idle ,
8189 onChange : func (f func ()) {
8290 s .mu .WithLock (f )
83- s .onChange (s .v )
91+ if s .onChange != nil {
92+ s .onChange (s .Get ())
93+ }
8494 },
8595 }
8696}
8797
8898func (s * safeStats ) InUse () statsItemAddr {
99+ s .mu .RLock ()
100+ defer s .mu .RUnlock ()
101+
89102 return statsItemAddr {
90103 v : & s .v .InUse ,
91104 onChange : func (f func ()) {
92105 s .mu .WithLock (f )
93- s .onChange (s .v )
106+ if s .onChange != nil {
107+ s .onChange (s .Get ())
108+ }
94109 },
95110 }
96111}
Original file line number Diff line number Diff line change @@ -3,6 +3,7 @@ package pool
33import (
44 "context"
55 "errors"
6+ "math/rand"
67 "sync"
78 "sync/atomic"
89 "testing"
@@ -289,3 +290,31 @@ func TestPool(t *testing.T) {
289290 }, xtest .StopAfter (42 * time .Second ))
290291 })
291292}
293+
294+ func TestSafeStatsRace (t * testing.T ) {
295+ xtest .TestManyTimes (t , func (t testing.TB ) {
296+ var (
297+ wg sync.WaitGroup
298+ s = & safeStats {}
299+ )
300+ wg .Add (10000 )
301+ for range make ([]struct {}, 10000 ) {
302+ go func () {
303+ defer wg .Done ()
304+ require .NotPanics (t , func () {
305+ switch rand .Int31n (4 ) { //nolint:gosec
306+ case 0 :
307+ s .Index ().Inc ()
308+ case 1 :
309+ s .InUse ().Inc ()
310+ case 2 :
311+ s .Idle ().Inc ()
312+ default :
313+ s .Get ()
314+ }
315+ })
316+ }()
317+ }
318+ wg .Wait ()
319+ }, xtest .StopAfter (5 * time .Second ))
320+ }
You can’t perform that action at this time.
0 commit comments