lib/db: Don't leak snapshot when closing (#6331)

We could potentially get a snapshot and then fail to get a releaser,
leaking the snapshot. This takes the releaser first and makes sure to
release it on snapshot error.
This commit is contained in:
Jakob Borg 2020-02-12 12:00:17 +01:00 committed by GitHub
parent a728743c86
commit d95a087829
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 8 deletions

View File

@ -37,14 +37,15 @@ func (b *leveldbBackend) NewReadTransaction() (ReadTransaction, error) {
}
func (b *leveldbBackend) newSnapshot() (leveldbSnapshot, error) {
snap, err := b.ldb.GetSnapshot()
if err != nil {
return leveldbSnapshot{}, wrapLeveldbErr(err)
}
rel, err := newReleaser(b.closeWG)
if err != nil {
return leveldbSnapshot{}, err
}
snap, err := b.ldb.GetSnapshot()
if err != nil {
rel.Release()
return leveldbSnapshot{}, wrapLeveldbErr(err)
}
return leveldbSnapshot{
snap: snap,
rel: rel,
@ -52,14 +53,15 @@ func (b *leveldbBackend) newSnapshot() (leveldbSnapshot, error) {
}
func (b *leveldbBackend) NewWriteTransaction() (WriteTransaction, error) {
snap, err := b.newSnapshot()
if err != nil {
return nil, err // already wrapped
}
rel, err := newReleaser(b.closeWG)
if err != nil {
return nil, err
}
snap, err := b.newSnapshot()
if err != nil {
rel.Release()
return nil, err // already wrapped
}
return &leveldbTransaction{
leveldbSnapshot: snap,
ldb: b.ldb,