Skip to content

Commit 433ef07

Browse files
author
Steve van Loben Sels
authored
Fixed a data race in the Hash balancer when using custom hasher (segmentio#335)
1 parent 11670d5 commit 433ef07

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

balancer.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ var (
134134
type Hash struct {
135135
rr RoundRobin
136136
Hasher hash.Hash32
137+
138+
// lock protects Hasher while calculating the hash code. It is assumed that
139+
// the Hasher field is read-only once the Balancer is created, so as a
140+
// performance optimization, reads of the field are not protected.
141+
lock sync.Mutex
137142
}
138143

139144
func (h *Hash) Balance(msg Message, partitions ...int) (partition int) {
@@ -142,7 +147,10 @@ func (h *Hash) Balance(msg Message, partitions ...int) (partition int) {
142147
}
143148

144149
hasher := h.Hasher
145-
if hasher == nil {
150+
if hasher != nil {
151+
h.lock.Lock()
152+
defer h.lock.Unlock()
153+
} else {
146154
hasher = fnv1aPool.Get().(hash.Hash32)
147155
defer fnv1aPool.Put(hasher)
148156
}

0 commit comments

Comments
 (0)