From 415adfbae6b52e2cd4fd8ed3cf4bdba0bb688cba Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 7 Sep 2020 10:31:33 +0200 Subject: [PATCH] lib/db: Don't hang on double iterator release with Badger (#6960) Since iterators must be released before committing or discarding a transaction we have the pattern of both deferring a release plus doing it manually. But we can't release twice because we track this with a WaitGroup that will panic when there are more Done()s than Add()s. This just adds a boolean to let an iterator keep track. --- lib/db/backend/badger_backend.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/db/backend/badger_backend.go b/lib/db/backend/badger_backend.go index 5af385d79..9b5f8dff7 100644 --- a/lib/db/backend/badger_backend.go +++ b/lib/db/backend/badger_backend.go @@ -334,6 +334,7 @@ type badgerIterator struct { first []byte last []byte releaseFn func() + released bool didSeek bool err error } @@ -397,6 +398,12 @@ func (i *badgerIterator) Error() error { } func (i *badgerIterator) Release() { + if i.released { + // We already closed this iterator, no need to do it again + // (and the releaseFn might hang if we do). + return + } + i.released = true i.it.Close() if i.releaseFn != nil { i.releaseFn()