From fcb89496ecc29040219cc5ef2bbc53a25486ed9c Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 2 Dec 2019 22:26:56 +0200 Subject: [PATCH] Prevent from possible deadlock in Set.WritePrometheus when Gague callback could call Set.mu.Lock --- set.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/set.go b/set.go index dfc0042..15976df 100644 --- a/set.go +++ b/set.go @@ -42,10 +42,14 @@ func (s *Set) WritePrometheus(w io.Writer) { if !sort.SliceIsSorted(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) } - s.mu.Unlock() w.Write(bb.Bytes()) }