Prevent from possible deadlock in Set.WritePrometheus when Gague callback could call Set.mu.Lock

This commit is contained in:
Aliaksandr Valialkin 2019-12-02 22:26:56 +02:00
parent ddbf13fd17
commit fcb89496ec

8
set.go
View File

@ -42,10 +42,14 @@ func (s *Set) WritePrometheus(w io.Writer) {
if !sort.SliceIsSorted(s.a, lessFunc) { if !sort.SliceIsSorted(s.a, lessFunc) {
sort.Slice(s.a, lessFunc) sort.Slice(s.a, lessFunc)
} }
for _, nm := range s.a { sa := append([]*namedMetric(nil), s.a...)
s.mu.Unlock()
// Call marshalTo without the global lock, since certain metric types such as Gauge
// can call a callback, which, in turn, can try calling s.mu.Lock again.
for _, nm := range sa {
nm.metric.marshalTo(nm.name, &bb) nm.metric.marshalTo(nm.name, &bb)
} }
s.mu.Unlock()
w.Write(bb.Bytes()) w.Write(bb.Bytes())
} }