From 129799328d5dab445f0b5ff4ca34ffd116f084d1 Mon Sep 17 00:00:00 2001 From: Oliver Tonnhofer Date: Fri, 8 Nov 2013 10:18:14 +0100 Subject: [PATCH] fix race condition where leveldb is closed before the iterator should solve assertion errors like: db/version_set.cc:710: leveldb::VersionSet::~VersionSet(): Assertion `dummy_versions_.next_ == &dummy_versions_' failed --- cache/nodes.go | 5 ++++- cache/relations.go | 5 ++++- cache/ways.go | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cache/nodes.go b/cache/nodes.go index 756ca3c..7586e97 100644 --- a/cache/nodes.go +++ b/cache/nodes.go @@ -86,6 +86,10 @@ func (p *NodesCache) Iter() chan *element.Node { ro := levigo.NewReadOptions() ro.SetFillCache(false) it := p.db.NewIterator(ro) + // we need to Close the iter before closing the + // chan (and thus signaling that we are done) + // to avoid race where db is closed before the iterator + close(nodes) defer it.Close() it.SeekToFirst() for ; it.Valid(); it.Next() { @@ -97,7 +101,6 @@ func (p *NodesCache) Iter() chan *element.Node { nodes <- node } - close(nodes) }() return nodes } diff --git a/cache/relations.go b/cache/relations.go index cd50173..c93014d 100644 --- a/cache/relations.go +++ b/cache/relations.go @@ -53,6 +53,10 @@ func (p *RelationsCache) Iter() chan *element.Relation { ro := levigo.NewReadOptions() ro.SetFillCache(false) it := p.db.NewIterator(ro) + // we need to Close the iter before closing the + // chan (and thus signaling that we are done) + // to avoid race where db is closed before the iterator + defer close(rels) defer it.Close() it.SeekToFirst() for ; it.Valid(); it.Next() { @@ -64,7 +68,6 @@ func (p *RelationsCache) Iter() chan *element.Relation { rels <- rel } - close(rels) }() return rels } diff --git a/cache/ways.go b/cache/ways.go index bc6e01e..f455df4 100644 --- a/cache/ways.go +++ b/cache/ways.go @@ -72,6 +72,10 @@ func (p *WaysCache) Iter() chan *element.Way { ro := levigo.NewReadOptions() ro.SetFillCache(false) it := p.db.NewIterator(ro) + // we need to Close the iter before closing the + // chan (and thus signaling that we are done) + // to avoid race where db is closed before the iterator + defer close(ways) defer it.Close() it.SeekToFirst() for ; it.Valid(); it.Next() { @@ -82,7 +86,6 @@ func (p *WaysCache) Iter() chan *element.Way { way.Id = idFromKeyBuf(it.Key()) ways <- way } - close(ways) }() return ways }