Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit bc2005d

Browse files
authored
Merge pull request #16 from Apsalar/master
locking: Prevent deadlock by making lock ordering consistent.
2 parents dbbe668 + 1300491 commit bc2005d

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

metrics.go

+17-14
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ import (
3434
"github.com/codahale/hdrhistogram"
3535
)
3636

37+
// Note - If multiple locks must be concurrently held they should be
38+
// acquired in this order hm, gm, cm or deadlock will result.
39+
3740
// A Counter is a monotonically increasing unsigned integer.
3841
//
3942
// Use a counter to derive rates (e.g., record total number of requests, derive
@@ -65,12 +68,12 @@ func (c Counter) SetFunc(f func() uint64) {
6568
// the given function, with an additional initializer function for a related
6669
// batch of counters, all of which are keyed by an arbitrary value.
6770
func (c Counter) SetBatchFunc(key interface{}, init func(), f func() uint64) {
68-
cm.Lock()
69-
defer cm.Unlock()
70-
7171
gm.Lock()
7272
defer gm.Unlock()
7373

74+
cm.Lock()
75+
defer cm.Unlock()
76+
7477
counterFuncs[string(c)] = f
7578
if _, ok := inits[key]; !ok {
7679
inits[key] = init
@@ -79,12 +82,12 @@ func (c Counter) SetBatchFunc(key interface{}, init func(), f func() uint64) {
7982

8083
// Remove removes the given counter.
8184
func (c Counter) Remove() {
82-
cm.Lock()
83-
defer cm.Unlock()
84-
8585
gm.Lock()
8686
defer gm.Unlock()
8787

88+
cm.Lock()
89+
defer cm.Unlock()
90+
8891
delete(counters, string(c))
8992
delete(counterFuncs, string(c))
9093
delete(inits, string(c))
@@ -139,14 +142,14 @@ func (g Gauge) Remove() {
139142

140143
// Reset removes all existing counters and gauges.
141144
func Reset() {
142-
cm.Lock()
143-
defer cm.Unlock()
145+
hm.Lock()
146+
defer hm.Unlock()
144147

145148
gm.Lock()
146149
defer gm.Unlock()
147150

148-
hm.Lock()
149-
defer hm.Unlock()
151+
cm.Lock()
152+
defer cm.Unlock()
150153

151154
counters = make(map[string]uint64)
152155
counterFuncs = make(map[string]func() uint64)
@@ -157,14 +160,14 @@ func Reset() {
157160

158161
// Snapshot returns a copy of the values of all registered counters and gauges.
159162
func Snapshot() (c map[string]uint64, g map[string]int64) {
160-
cm.Lock()
161-
defer cm.Unlock()
163+
hm.Lock()
164+
defer hm.Unlock()
162165

163166
gm.Lock()
164167
defer gm.Unlock()
165168

166-
hm.Lock()
167-
defer hm.Unlock()
169+
cm.Lock()
170+
defer cm.Unlock()
168171

169172
for _, init := range inits {
170173
init()

0 commit comments

Comments
 (0)