From 754eac676d07453abd9e96b88132d4f663756d2e Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 22 Jul 2020 21:46:38 +0300 Subject: [PATCH] lib/storage: prevent possible race condition when all the goroutines exit Storage.AddRows, before goroutines other goroutines are blocked on searchTSIDsCond inside Storage.searchTSIDs This condition may occur after the following sequence of events: 1) A goroutine enters the loop body when len(addRowsConcurrencyCh) == cap(addRowsConcurrencyCh) inside Storage.searchTSIDs. 2) All the goroutines return from Storage.AddRows. 3) The goroutine from step 1 blocks on searchTSIDsCond.Wait() inside the loop body. The goroutine remains blocked until the next call to Storage.AddRows, which calls searchTSIDsCond.Signal(). This may take indefinite time. --- lib/storage/storage.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/storage/storage.go b/lib/storage/storage.go index 4c009e3ef..ee5a37066 100644 --- a/lib/storage/storage.go +++ b/lib/storage/storage.go @@ -1112,8 +1112,10 @@ func (s *Storage) AddRows(mrs []MetricRow, precisionBits uint8) error { putRawRows(rr) // Notify blocked goroutines at Storage.searchTSIDs that they may proceed with their work. + searchTSIDsCondLock.Lock() <-addRowsConcurrencyCh searchTSIDsCond.Signal() + searchTSIDsCondLock.Unlock() return err }